質問: stream().parallel() ``` こうすることで、以下のような記述ができます。 ``` (1..100 step 2).parallel().forEach{ println(it) } ``` 意図している動作はご理解いただけるかと思います。 --- ### 質問 こんなの元々組み込んであってもよさそうな気もするのですが、ないのは何かマズい点や理由があるからなのでしょうか。 IntProgression は iterator、IntStream は stream というのはわかるのですが、だからダメとはならないと思います。
回答: Kotlinのライブラリーインターフェースについて学び始めでしかないので間違ってたらすみません。 > > だからダメとはならないと思います > > > 想像ですが「標準機能として提供するのは、慎重に考えないとインターフェース破綻の危険があるのではないか」と思います。 KotlinにはIterableとSequenceなどの独自インターフェースがありますね。IntProgressionはKotlin独自のIterableです。IterableがJavaと同様のインターフェースに見えるのになぜわざわざKotlin独自にしているかといえば、Kotlin Iterableがjavaのそれとは異なる機能を備えているからだと思います。例えばJavaではjava.util.stream.Streamでしかリッチなパイプライン機能(変換や集約といったもの)が使えません。一方、KotlinのIterableは拡張関数の力を借りてJavaのIterableよりずっと高機能になっていますね。要するに似てるけど別なインターフェースと言えましょう。 次に並列処理機能について考えると、JavaのStreamにあるparallelはKotlinには見当たりません。コルーチンがまだexperimentalですが、Kotlinはこれなどを用いてJavaとは違う戦略で並列処理機能を設計しようとしているような気がします。 以上から、「KotlinのIterableにJavaのStream固有のparallelを直接記述できるようにしてしまうとKotlinのIterableインターフェースが破たんしかねないのではないか」と想像しました。 余談: ところで、Kotlin 1.1だと(1..2).asSequence().asStream()のようにするとStreamに変換できるようです。このように明示的に変換する分には混乱はないので一つの方法であるとは思います。 ただ・・・ `(1..1000).asSequence().asStream().parallel().forEach(...)` という書き方を考えると、なんだか簡潔とは言い難いですし、それ以上にasStream()が効率よく並列動作できるようなSpliteratorを作ってくれるかが気になります。後者は並列処理のオーバーヘッド(※)にかかわります。その点がどうなっているか不明ですが、Stream#parallelを使うなら、最初からIntStream.rangeを使った方が素直だし安心な気がします。 ※: オーバーヘッド 複数スレッド用にパイプラインを分割する際に、一旦上流のパイプラインから一定要素を取り出して配列として蓄積する段取りをふまないと並列動作を始められないことを指します。IntStream.rangeで生成されるIntStreamはこんな処理を必要とせず、S~EのストリームをS~S+PとS+P+1~Eの2つのストリームに即座に分割し並列動作を開始できます。