Почему фильтр перед foldLeft медленнее в Scala?

Я написал ответ на первый вопрос Project Euler :

Сложите все натуральные числа меньше одной тысячи, которые кратны 3 или 5.

Первое, что пришло мне в голову, было:

(1 until 1000).filter(i => (i % 3 == 0 || i % 5 == 0)).foldLeft(0)(_ + _)

, но это медленно (занимает 125 мс), поэтому я переписал его, просто думая о «другом пути» по сравнению с «более быстрым»

(1 until 1000).foldLeft(0){
    (total, x) =>
        x match {
            case i if (i % 3 == 0 || i % 5 ==0) => i + total // Add
            case _ => total //skip
        }
}

Это намного быстрее (всего 2 мс). Почему? Я предполагаю, что вторая версия использует только генератор Range и никоим образом не проявляет полностью реализованную коллекцию, делая все это за один проход, быстрее и с меньшим объемом памяти. Я прав?

Вот код на IdeOne: http://ideone.com/GbKlP

21
задан Zero Piraeus 22 January 2015 в 17:20
поделиться