Ads
Comments 47
Круто, прикольно, но где тут новый способ? Я вижу тут лишь необычную реализацию стандартного способа.
А вы таки хотите способ вычисления факториала без перемножения чисел от 1 до N? Ну, можно по формуле Стирлинга, или через гамма-функцию Эйлера. Но это уже статья в другой хаб.
Многие скажут, что первый способ лучше, но это не так. Во-первых, циклы уже не в тренде, сейчас модно функциональное программирование.


Аргументация уровня журнала Cosmopolitan
Ну, такие заявления нельзя делать без тестов. Нужно замерить перформанс в каждом конкретном случае.
Не совсем понимаю, о каких конкретных случаях речь, я говорил о самом банальном сравнении, которое вы дали в начале.На любом тесте, который бы я не находил на jsPerf, цикл выигрывал с довольно большим отрывом. И да, я не делал заявлений, я как раз таки задал вопрос, так как самому интересно.
Если отвечать серьёзно, то разумеется, цикл будет быстрее рекурсии. Я не уверен, можно ли как-то оптимизировать ещё сильнее, но из наивных реализаций цикл точно самый быстрый.
Чтобы не быть голословными: https://jsperf.com/fastest-factorial

(1) cycle: 3.700.000 op/sec
(2) recursion: 1.450.000 op/sec
(3) eval: 500 op/sec
Возможно вам будет полезно посмотреть доклад Вячеслава Егорова, человека который участвовал в разработке V8. Узнаете много нового о перфоманс тестах в JS.
А разве без теста не очевидно, что в обоих случаях выполняется одно и то же действие (перемножение чисел), только при рекурсии программа «распухает» за счёт вызова функции (самой себя) и передачи (копирования) ей данных?
Вообще да, но в данном случае нет. В то время, как наши космические корабли бороздят просторы вселенной, а в процессорах, компиляторах и интерпретаторах множатся неочевидные оптимизации, очевидных с точки зрения перформанса вещей становятся всё меньше. В комментарии выше я написал «разумеется», поскольку изучил вопрос и выяснил, что в современных js-движках рекурсия не оптимизирована. Без этого знания ответ не является очевидным.
Возможно это и откровение с точки зрения факториала, а вот с точки зрения js кода этому творению место на свалке.
Сильное заявление. Аргументировать его вы, конечно, не будете?
Скажите пожалуйста, а зачем в примере с рекурсией второй параметр? И что в него передается при вызове?
Ну, собственно, да. Иначе можно было бы написать function factorial(n){return !n? 1: factorial(n-1)}. Но в таком случае, несмотря на то, что рекурсивный вызов стоит последним, это не будет хвостовой рекурсией, потому что последним вычисляемым выражением будет значение тернарного оператора.
Во-вторых, чем больше людей используют второй способ, тем быстрее в основных джаваскриптовых движках появится оптимизация

То есть давайте все ходить через лес, тогда там быстрее появится дорога.
Там, где ходят люди, протаптываются тропинки этими самыми людьми. А потом там кладут асфальт и облагораживают дорожки.
Это если в 10 метрах уже не проложена дорога. По которой все ходят. И тут появляется такой человек, который хочет дорогу на 10 метров ближе к своему дому и говорит: ходите все через лес, в грязь, в снег, тогда через несколько лет тут будет дорога…
А имеющаяся дорога — это циклы.
Я не понимаю, что Вам не нравится. Основную дорогу никто не закроет же.
Ваш код настолько идеален, что изобретает новую математику: по мнению вашего алгоритма, 50! = 3. В чем тогда смысл такого запутанного кода, который ни поддерживать, ни отлаживать невозможно?
Ну, в некотором смысле это действительно 3. Если быть точным, 3.0414093201713376e+64.
UFO landed and left these words here
Кстати да, я думал об этом, но потом самомодифицирующийся код захватил мою голову.
Господи боже, мы наконец-то дожили до сложения чисел с помощью JQuery!
Сарказм, конечно же, но все-таки…
var React = require("react");

var Factorial = React.createClass({
    render: function(){
        var result = this.props.result || 1,
            n = this.props.n;
        if(!n){
        return <span>{result}</span>
    }else{
        return <Factorial n={n - 1} result={result*n}/>
    }
    }
});
module.exports = Factorial;

Вот это вот? Выглядит солиднее? С кусками разметки? Это как в современном мире называется — шутка, сарказм или что?

Как-то слишком примитивно, я считаю. Нужно подключить несколько фреймворков, зафигачить с десяток микросервисов, общающихся через REST, утащить это всё в облако, подключить CDN… Короче, тема не раскрыта.

Да, что-то пропустил. Но таким вот образом можно поставить в тупик неканоничным решением задачи.

UFO landed and left these words here
Да никаких проблем:
var factorial = n => Math.round(Math.sqrt(2 * Math.PI * n) * Math.pow((n / Math.E), n) * Math.exp(1 / (12 * n) - 1 / (360 * n * n * n)));
UFO landed and left these words here
Так-так, а что мешает взять формулу Стирлинга за определение факториала нецелого числа?
Кроме, конечно, требования о непрерывности, которого у нас, впрочем, и нет.

(комментарий оставлен в рамках федеральной целевой программы "говорить классным людям, что они классные")


Эта статья, как и многие другие ваши статьи, восхитительно прекрасна. Пишите ещё, пожалуйста.

Only those users with full accounts are able to leave comments. , please.