Я не думаю, что ваше сравнение очень надежное. Очень сложно что-либо сказать об относительной синхронизации очень быстрого кода, не запуская его много раз, чтобы получить среднее значение - слишком много неконтролируемых факторов могут немного изменить время выполнения.
Вывод, который я могу сделать из приведенных ниже тестов заключается в том, что инкапсуляция довольно тривиального вычисления в избыточном для l oop не сильно ранит , но любое очевидное преимущество является тривиальным и, вероятно, просто эффектом шума.
I инкапсулировал каждый из ваших кусков кода в функцию (with_loop
и without_loop
), поместив function() { ... }
вокруг каждого из них. (Обратите внимание, что это означает, что я не основываю время на ваших Sys.time()
сравнениях, а на встроенном времени в пакете microbenchmark
.)
Пакет microbenchmark
больше подходит для бенчмаркинга особенно для очень коротких вычислительных задач: из ?microbenchmark::microbenchmark
:
'microbenchmark' служит более точной заменой часто встречающегося выражения system.time (replicate (1000, expr)) '. Он изо всех сил старается точно измерить только время, необходимое для оценки «expr». Для достижения этого используются функции точной синхронизации, составляющие менее миллисекунды (предположительно наносекунды), которые предоставляют большинство современных операционных систем. Кроме того, все вычисления выражений выполняются в коде C, чтобы минимизировать любые издержки.
library(microbenchmark)
m1 <- microbenchmark(with_loop, without_loop)
library(ggplot2)
autoplot(m1)+scale_y_log10()
Квантили (lq, медиана, uq) практически идентичны.
Unit: nanoseconds
expr min lq mean median uq max neval cld
with_loop 36 38 48.56 39 40 972 100 a
without_loop 36 39 177.81 40 41 13363 100 a
![enter image description here](https://i.stack.imgur.com/AAIEf.png)
Код без l oop действительно медленнее в среднем (то есть имеет большее среднее значение ), но это почти полностью обусловлено парой выбросов.
Теперь сосредоточимся только на значениях менее 50 наносекунд:
autoplot(m1)+scale_y_log10(limits=c(NA,50))
![enter image description here](https://i.stack.imgur.com/FWfSJ.png)
Если мы сделаем это снова с times=1e6
(миллион итераций), мы получим почти идентичные результаты: среднее значение с l oop будет на 3 наносекунд быстрее (опять же, вероятно, почти полностью обусловлено небольшие колебания в верхнем хвосте).
Unit: nanoseconds
expr min lq mean median uq max neval cld
with_loop 32 39 86.44248 41 61 2474675 1e+06 a
without_loop 35 39 89.86294 41 61 2915836 1e+06 a
Если вам нужно запустить l oop миллиард раз, это будет соответствовать 3-секундной разнице во времени выполнения. Наверное, не стоит беспокоиться.