Задать вопрос
@valis

Почему JS решил задачу на рекурсию гораздо быстрее Python/Lua?

Есть задача 14 из проекта Эйлера.
Суть задачи есть следующая повторяющаяся последовательность определена для множества натуральных чисел:
n → n/2 (n - чётное)
n → 3n + 1 (n - нечётное)
Какой начальный элемент меньше миллиона генерирует самую длинную последовательность?

Решение задачи рекурсионное. В рамках канала https://www.youtube.com/watch?v=mHbgWHqeBp0 (да качество пока ужасное) я сделал сравнение производительности в решении данной задачи на Python/LUA (код не буду приводить он примерно такой же как и JS)

console.time('coll');
function getCollatz(number, iterations=1){
    if (number===1){
        return iterations
    } else if (number % 2 === 0){
        return getCollatz(Math.floor(number/2), iterations+1)
    } else {
        return getCollatz(3*number+1, iterations+1)
    }
}

let a = 0;
let x = 0;
let y = 0

for (let i = 1; i< 1000001; i++){
    let current_iter = getCollatz(i);
    if (current_iter>a){
        a = current_iter;
        x = i
    }
    y++
}
console.timeEnd('coll')
console.log(x)


Цифры получились такие:
  1. Python: 59 сек
  2. Lua: 17 сек


Для меня пока без сюрпризов, но JS на NodeJS справился за 2 секунды!!!!
Собственно вопрос - почему?

P.S. Все 3 теста на одной и той же машине
  • Вопрос задан
  • 548 просмотров
Подписаться 2 Простой 12 комментариев
Ответ пользователя Дмитрий Беляев К ответам на вопрос (4)
bingo347
@bingo347 Куратор тега JavaScript
Crazy on performance...
Синтетические бенчмарки врут практически всегда, потому что те кто их пишет редко знает досконально все сравниваемые технологии и вряд ли сможет свести задачу к схожим условиям. Как правило, схожие условия выходят только при отключении всех возможных оптимизаций, ибо оптимизации у разных технологий работают по разному.
Как уже написали выше, Вы зря не превели код на Python, возможно специалисты по этому ЯП предложили бы более оптимальное решение.
По js варианту могу сказать, что v8 очень хорошо умеет оптимизировать хвостовую рекурсию. И в данном примере вместо дорогой рекурсии у Вас будет работать более дешевый цикл. Я могу Вас удивить, перепишите свое решение на C вот прямо как есть и скомпилируйте без оптимизаций - js + v8 окажется быстрее
Ответ написан
Комментировать