PartialFunctionの戻り値は必ずboxingされる

相変わらず、noboxというライブラリを作ってる途中で気づいた、(普通は気にする必要ない)細かいパフォーマンスの話です。
気づいた経緯は以下のような感じ

というわけで、「withFilterしてmap」という処理を、最初は単にPartialFunction作って(自分が実装した)collectを呼んでいたのですが、それをやめてPartialFunction使わないようにしたら、無事「filterしてmap*1」するよりも2倍程度は速くなりました。
そして、そのwithFilterの実装を入れた、v0.1.5をreleaseしておきました。

https://bintray.com/xuwei-k/maven/nobox/0.1.5
https://github.com/xuwei-k/nobox/tree/v0.1.5

相変わらずグラフを見ると、誰も使っていない感じですが*2

https://bintray.com/xuwei-k/maven/nobox?from=statistics

使ってもらうことより、実装していくことにより勉強するのが目的なので、まぁ飽きるまで続けます。
といっても、そろそろ簡単に改善できる部分はなくなってきているのですが・・・。



さて、noboxのライブラリの説明ばかりで、タイトルの件の説明してなかったので、ここから説明します。versionはScala2.10.3とScala2.11.0-M6時点です。*3

ポイントを箇条書きにすると

という理由です。*5
*6
ところで、Scala2.9以前だとAbstractPartialFunctionもないしapplyOrElseもないので、違う結果になるかもしれませんが、まだ試してません。追記

以下のようなコードで簡単なベンチマークとったら

Scala2.9のほうがScala2.10より速い結果がでた・・・。
この微妙に遅い(?)というデメリットを打ち消すほどに、「Scala2.10からapplyOrElseを新規に追加し、applyからapplyOrElseを呼ぶという実装にした」のはメリットがあったのか謎・・・。applyOrElseを追加するにしても、さらにもう少し工夫してboxing防ぐことはできなかったのか・・・?

*1:つまり、filterした後に、一旦中間オブジェクトが生成される

*2:グラフ中でいくつかDownloadがあるのは、ちゃんとファイルがuploadされてるか確かめるために、自分がdownloadしたもんがほとんど

*3:2.10.3と2.11.0-M6で、このあたりにほぼ違いは無さそう

*4:パフォーマンス面を除けば

*5:もしこの推測間違ってたらだれか教えてください・・・。-Xprint:jvmした結果を元に予想しただけで、javapしたり、その他プロファイラを使って確かめたわけではありません。

*6:明示的にnew PartialFunctionとインスタンス生成して、applyをoverrideする場合はboxingされません。が、ほとんどの場合PartialFunctionはそんな使い方しませんし、よっぽどのことが無い限り、boxing避けるためにnew PartialFunctionと書いてapplyをoverrideするのは馬鹿げています