Time.now срещу Time.new в Ruby

Има ли някаква разлика между Time.now и Time.new (без параметри)? Може да има разлика в управлението на паметта или някои дребни детайли?


person Paul    schedule 03.11.2014    source източник
comment
Ако знаехте, че now е псевдоним на new, трябваше да го кажете във въпроса, тъй като това щеше да ни помогне да разберем какво търсите. Очаквам да знаете това, като се има предвид, че документът за Time.new (версия 2.1.4 така или иначе) се състои от един ред, псевдоним за ::new. Връща обект Time, инициализиран към текущото системно време..   -  person Cary Swoveland    schedule 03.11.2014


Отговори (3)


now е псевдоним на new. Няма разлика между тях. Джеф Прайс трябва да отговори (и отговорът му също е правилен, моля, гласувайте за отговора му, ако това ви харесва) първо, защото пишех и изпълнявах този бенчмарк:

Ruby 2.1.2(MRI):

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 итерации виждате само няколко стотни/секунда разлика, която в реалния живот ще бъде значително компенсирана от събирането на боклука, I/O и подсистемите на OS. С други думи, не си струва да се притеснявате и се равнява на преждевременна оптимизация. Вижте също документацията за 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