Я увидел вопрос Why does Process.fork make stuff slower in Ruby on OS X? и смог определить, что Process.fork
делает не действительно делает задачи, в общем, медленнее.Почему `Time.utc` медленнее в разветвленном процессе в Ruby на OS X (а не на Python)?
Однако, как представляется, Time.utc
, в частности, намного медленнее.
require 'benchmark'
def do_stuff
50000.times { Time.utc(2016) }
end
puts "main: #{Benchmark.measure { do_stuff }}"
Process.fork do
puts "fork: #{Benchmark.measure { do_stuff }}"
end
Вот некоторые результаты:
main: 0.100000 0.000000 0.100000 ( 0.103762)
fork: 0.530000 3.210000 3.740000 ( 3.765203)
main: 0.100000 0.000000 0.100000 ( 0.104218)
fork: 0.540000 3.280000 3.820000 ( 3.858817)
main: 0.100000 0.000000 0.100000 ( 0.102956)
fork: 0.520000 3.280000 3.800000 ( 3.831084)
Один ключ может быть, что выше, происходит на OS X, в то время как на Ubuntu, не кажется, что будет разница:
main: 0.100000 0.070000 0.170000 ( 0.166505)
fork: 0.090000 0.070000 0.160000 ( 0.169578)
main: 0.090000 0.080000 0.170000 ( 0.167889)
fork: 0.100000 0.060000 0.160000 ( 0.169160)
main: 0.100000 0.070000 0.170000 ( 0.170839)
fork: 0.100000 0.070000 0.170000 ( 0.176146)
Может ли кто-нибудь объяснить эту странность?
Дальнейшие исследования:
@tadman предположил, что это может быть ошибка в/OS времени X кода MacOS, так что я написал подобный тест в Python:
from timeit import timeit
from os import fork
print timeit("datetime.datetime.utcnow()", setup="import datetime")
if fork() == 0:
print timeit("datetime.datetime.utcnow()", setup="import datetime")
else:
pass
Опять же, на Ubuntu , контрольные показатели одинаковы для разветвленных/основных процессов. В OS X, однако, раздвоенный процесс теперь немного быстрее, чем основной процесс, который является противоположным поведением в Ruby.
Это заставляет меня думать, что источник «штрафного удара» находится в реализации Ruby, а не в реализации OS X.
Это штраф за уровень вилки, как если бы он был двойным, если в другой суб-вилке? Означает ли это наказание, если родительский процесс завершается? Используется ли это внутри потоков? – tadman
@tadman Прохладные вопросы. Это не штраф за уровень вилки; вилка следующего уровня имеет то же самое время выполнения, что и первая вилка. Я проверю остальные сценарии, если смогу. –
Я наблюдаю то же поведение, что и с Ruby 2.3.3 на macOS 10.12, но не могу воспроизвести его на Fedora. Вероятно, это проблема с временным кодом на macOS, поэтому, возможно, стоит написать отчет об ошибке. Я считаю, что по какой-то причине это изолировано от временных функций. – tadman