reduce
и apply
, конечно, только эквивалентны (с точки зрения возвращаемого конечного результата) для ассоциативных функций, которые должны видеть все свои аргументы в случае переменной арности. Когда они эквивалентны по результату, я бы сказал, что apply
всегда совершенно идиоматичен, в то время как reduce
эквивалентен - и может сбрить частичку глаза - во многих распространенных случаях , Далее следует мое обоснование, что я верю в это.
+
сам по себе реализован в терминах reduce
для случая переменной арности (более 2 аргументов). Действительно, это кажется очень разумным способом «по умолчанию» для любой переменной ассоциативной функции: reduce
имеет потенциал для выполнения некоторых оптимизаций, чтобы ускорить процесс - возможно, с помощью чего-то вроде internal-reduce
, новинки 1.2 недавно отключили в master, но, надеюсь, будут введены в будущем - что было бы глупо воспроизвести в каждой функции, которая может быть полезна в случае vararg. В таких распространенных случаях apply
просто добавит немного накладных расходов. (Обратите внимание, что беспокоиться не о чем.)
С другой стороны, сложная функция может использовать некоторые возможности оптимизации, которые не являются достаточно общими, чтобы быть встроенными в reduce
; тогда apply
позволит вам воспользоваться этим, в то время как reduce
может на самом деле замедлить вас. Хороший пример последнего сценария, происходящего на практике, представлен str
: он использует StringBuilder
внутри и значительно выиграет от использования apply
вместо reduce
.
Итак, я бы сказал, используйте apply
, если сомневаетесь; и если вам случится узнать, что он ничего не покупает за reduce
(и что это вряд ли изменится очень скоро), не стесняйтесь использовать reduce
, чтобы избавиться от этих крошечных ненужных накладных расходов, если вам так хочется.