Проблема здесь в том, что ArrayBuffer
параметризован, поэтому в действительности он хранит ссылки на Object
. Любая ссылка на Int
автоматически упаковывается и распаковывается по мере необходимости, что делает его очень медленным. Это невероятно медленно с Scala 2.7, который использует для этого примитив Java, который делает это очень медленно. Scala 2.8 использует другой подход, делая его быстрее. Но любой бокс / распаковка замедлит вас. Кроме того, вы сначала просматриваете ArrayBuffer
в куче, а затем снова ищите java.lang.Integer
, содержащий Int
- два обращения к памяти, что делает его медленнее, чем другое решение.
Когда коллекции Scala станут специализированными, это должно произойти намного быстрее. Будет ли этого достаточно, чтобы победить вашу вторую версию или нет, я не знаю.
Теперь, что вы можете сделать, чтобы обойти это - использовать Array
вместо этого. Поскольку Java Array
не стирается, вы избегаете упаковки / распаковки.
Кроме того, когда вы используете для-понимания, ваш код эффективно сохраняется в методе, который вызывается для каждого элемента. Таким образом, вы также делаете много вызовов методов, что является еще одной причиной, по которой это происходит медленнее. Увы, кто-то написал плагин для Scala, который оптимизирует хотя бы один случай для понимания, чтобы избежать этого.