19 авг. 2015 г.

Глубина стека JavaScript (дубль 3)

Продолжение (первая часть, вторая часть)

Баг в Firefox подсказал, что глубина стека зависит ещё и от метода вызова (fn(), fn.call(), fn.apply()), и от контекста функции (fn.call(null) или fn.call(this)), и от платформы (Firefox 39/Win vs. Firefox 39/Linux). В одном из комментариев было указано, что при переходе с прямого вызова fn() на fn.call() в версии Firefox под Linux глубина стека уменьшалась с 7000 до 500.

Добавил в скрипт подсчёт глубины стека при использовании call.

Результаты

Windows 7 64-bit:
Chrome 44:    глубина стека не зависит от метода вызова
Safari 5.1.7: глубина стека не зависит от метода вызова
IE11:         fn() 2800..2300, fn.call() 1900..1700
Firefox 39:   fn() 8400..4800, fn.call() 7200..5600

Windows 10:
Edge:         fn() 5000,80026..81336, fn.call() 5207..5291
Firefox Dev. edition 43.0a2: fn() 3500..3000, fn.call() 4400..3300

Интересные факты:

  • В Firefox/Win при отсутствии передаваемых аргументов прямой вызов fn() иногда занимает меньше памяти в стеке, чем fn.call(this), при наличии аргументов - всегда fn.call(this, arg) занимает меньше, чем fn(arg).
  • В Firefox/Linux fn.call() в некоторых случаях даёт на порядок меньшую глубину стека.
  • В IE11 fn.call() даёт в 1.3 - 1.4 раза меньшую глубину стека.
  • В Edge первый запуск может дать глубину стека fn() около 5000, последующие запуски дают глубину стека около 80000