Time.now против Time.new в Ruby

Есть ли разница между Time.now и Time.new (без параметров)? Может разница в управлении памятью или какие-то мелкие детали?


person Paul    schedule 03.11.2014    source источник
comment
Если бы вы знали, что now является псевдонимом для new, вы должны были указать это в вопросе, так как это помогло бы нам понять, что вам нужно. Я полагаю, вы знали об этом, учитывая, что документ для Time.new (по крайней мере, версия 2.1.4) состоит из одной строки Alias ​​for ::new. Возвращает объект Time, инициализированный текущим системным временем.   -  person Cary Swoveland    schedule 03.11.2014


Ответы (3)


now — это псевдоним для new. Между ними нет никакой разницы. Джефф Прайс должен ответить (и его ответ также правильный, пожалуйста, проголосуйте за его ответ, если вам это нравится) первым, потому что я писал и запускал этот тест:

Ruby 2.1.2 (МРТ):

Rehearsal ----------------------------------------------------------------------------
Time.new                                   0.670000   0.000000   0.670000 (  0.679709)
Time.now                                   0.880000   0.010000   0.890000 (  0.881899)
------------------------------------------------------------------- total: 1.560000sec

                                               user     system      total        real
Time.new                                   0.720000   0.000000   0.720000 (  0.719453)
Time.now                                   0.740000   0.010000   0.750000 (  0.742711)

Rehearsal ----------------------------------------------------------------------------
Time.new                                   0.810000   0.000000   0.810000 (  0.811874)
Time.now                                   0.830000   0.000000   0.830000 (  0.831346)
------------------------------------------------------------------- total: 1.640000sec

                                               user     system      total        real
Time.new                                   0.790000   0.010000   0.800000 (  0.800082)
Time.now                                   0.740000   0.000000   0.740000 (  0.749995)

Rehearsal ----------------------------------------------------------------------------
Time.new                                   0.680000   0.010000   0.690000 (  0.690337)
Time.now                                   0.850000   0.000000   0.850000 (  0.856800)
------------------------------------------------------------------- total: 1.540000sec

                                               user     system      total        real
Time.new                                   0.790000   0.010000   0.800000 (  0.792666)
Time.now                                   0.770000   0.000000   0.770000 (  0.777414)

Rehearsal ----------------------------------------------------------------------------
Time.new                                   0.590000   0.010000   0.600000 (  0.594650)
Time.now                                   0.710000   0.010000   0.720000 (  0.717067)
------------------------------------------------------------------- total: 1.320000sec

                                               user     system      total        real
Time.new                                   0.870000   0.000000   0.870000 (  0.872646)
Time.now                                   0.680000   0.010000   0.690000 (  0.687092)

Rehearsal ----------------------------------------------------------------------------
Time.new                                   0.780000   0.010000   0.790000 (  0.786419)
Time.now                                   0.780000   0.000000   0.780000 (  0.789049)
------------------------------------------------------------------- total: 1.570000sec

                                               user     system      total        real
Time.new                                   0.760000   0.010000   0.770000 (  0.768194)
Time.now                                   0.790000   0.010000   0.800000 (  0.790981)

Запустите тест самостоятельно:

n = 1000000

5.times do 
  Benchmark.bmbm(40) do |x|
    x.report("Time.new"){ n.times { Time.new } }
    x.report("Time.now"){ n.times { Time.now } }
  end
end
person Surya    schedule 03.11.2014
comment
Сравнительные тесты не покажут существенной разницы между new и now, поскольку now является псевдонимом new. Любые различия связаны с системными процессами или сборкой мусора и в основном представляют собой случайный шум, возникший во время теста. - person the Tin Man; 03.11.2014
comment
@theTinMan: На самом деле, я провел тест примерно 5 раз для каждой версии Ruby, прежде чем опубликовать его здесь. Если бы разница была связана с системными процессами или сборкой мусора или из-за любого случайного шума, который возник во время теста, то результаты времени, затраченного Time.new, не должны были быть значительно меньше для всех 5 прогонов. - person Surya; 03.11.2014
comment
Я согласен с тем, что эти компоненты действительно влияют на тест, но разве это не должно влиять на него в обоих случаях вместо того, чтобы быть предвзятым к Time.new? - person Surya; 03.11.2014
comment
Единственная разница в том, что now вызывает new. Это очень, очень незначительное наращивание и разрушение стека и вызова подпрограммы в C. ...значительно меньше...? За 1 000 000 итераций вы видите разницу всего в несколько сотых в секунду, которая в реальной жизни будет значительно компенсирована сборкой мусора, вводом-выводом и подсистемами ОС. Другими словами, об этом не стоит беспокоиться, и это равносильно преждевременной оптимизации. Также см. документацию для bmbm. - person the Tin Man; 03.11.2014
comment
@theTinMan: Хорошо, мой плохой, немного меньше. Я немного покопался в time.c и обнаружил, что now на самом деле вызывает rb_class_new_instance, в то время как new time_init_0 (в случае, если аргумент не передается), который создает текущее время и немедленно возвращается, а rb_class_new_instance переходит к object.c, который в конечном итоге выделяет новый объект класса, то есть вызовет new. Итак, да, это псевдоним, но он должен пройти через другие методы, чтобы добраться до фактического. Согласен, что это не такая уж и животрепещущая тема. Кстати, спасибо за ваш вклад. Я всегда узнаю что-то новое от таких людей, как ты. :) - person Surya; 03.11.2014
comment
Измените порядок .now и .new и вернитесь к нам. В моих тестах тот, кто работал вторым, был быстрее. Неважно какой. - person Jeff Price; 03.11.2014
comment
Я сделал. По-прежнему не так много изменений, для первого запуска немного больше, чем now, но в других 4 запусках new снова немного меньше, чем now. Вам не нужно было голосовать против только из-за этого. Я никогда не говорил, что они разные, я просто опубликовал тест их производительности, слово «разница» было использовано theTinMan, я, кстати, не вижу, как ответ вводит кого-либо в заблуждение. - person Surya; 03.11.2014

Нет никакой разницы.

Time.now — это псевдоним ::new. Возвращает объект Time, инициализированный текущим системным временем.

http://www.ruby-doc.org/core-2.1.4/Time.html#method-c-now

person Jeff Price    schedule 03.11.2014
comment
Для меня не во всех случаях одинаково... 2.2.4 :010 > Timecop.freeze(Chronic.parse("February First")) => 2017-02-01 12:00:00 -0800 2.2.4 :011 > Time.now => 2017-02-01 12:00:00 -0800 2.2.4 :012 > Time.new => 2016-11-01 11:10:20 -0700 - person nroose; 01.11.2016
comment
@nroose Старая ошибка в Timecop? github.com/travisjeffery/timecop/issues/17 - person Vanuan; 09.10.2019

Использование Ruby 2.4.1 и Rails 5.0.3 При использовании travel_to в тестах Time.new не зависит от него, но Time.now из-за него изменяется

person Natan Rubinstein    schedule 28.02.2019
comment
И это печально :(. Но я думаю, что мы должны избегать использования Time.new в значении Time.now. В этом случае мы стреляем в две мишени :). Читабельность и проблемы с travel_to. - person Евгений Масленк&; 28.05.2019