#Scala で #Hadoop のjava.lang.Iterable[Writable]を処理する際の話

4
Takuya UESHIN @ueshin

なんか考え違いをしているかも。

2012-12-26 15:40:53
Akihiro Okuno @choplin

@ueshin すいません、二回目に使いまわす時は仰る通りメモリに載りますね… メモリ消費量云々は一回目の走査の時の話でした。

2012-12-26 15:56:09
Kenji Yoshida @xuwei_k

@choplin @ueshin 2回使わないなら、java.lang.Iterableのiteratorを一旦明示的に呼んで、それをScalaのIteratorに変換したほうが効率はよさそうですが(それだと結局さっきのように駄目なのかな)

2012-12-26 16:00:09
Kenji Yoshida @xuwei_k

@choplin @ueshin あと、もしStreamにして(2回使って)一旦メモリ上に持つ(かつそれをその後、結合とかあまりしない)くらいなら、普通にArrayにしたほうがメモリの効率はいいかもしれませんね

2012-12-26 16:08:25
Kenji Yoshida @xuwei_k

@choplin IntWritableよくわかってないですがhttp://t.co/EwuuEOte 可能ならIterableに対して.iterator.asScala.map{_.get}.toArray とすれば、プリミティブ型のArrayになって更にメモリ節約になるとか?

2012-12-26 16:12:30
Akihiro Okuno @choplin

@xuwei_k 問題のiteratorは、nextで内部の値を変えた同じオブジェクトを返し続けるんですが、毎回値を取り出して処理すれば恐らく大丈夫かと。ただ、元々の目的はscalaのコレクションAPIで色々と操作することだったので、任意のコレクションに落としこみたかったのです。

2012-12-26 16:12:59
Akihiro Okuno @choplin

@xuwei_k はい。コレクションをメモリに置いて複数回使うならArrayがいいと思います。ただ単純にIterable.toArrayを呼ぶと全部末尾の値に置き換わるので、ご指摘の通りmapを通す必要があるという罠が。.get自体は単にIntを返すのでメモリには効きそうです。

2012-12-26 16:18:22
Kenji Yoshida @xuwei_k

あーあと、Scalaでプリミティブ型の値を大量に扱うなら、(唯一Boxingを避けるために最適化されてる)WrappedArrayとか、 BoxingなしにプリミティブのArrayを手続き的に作るためのArrayBuilderとかの使用も検討したほうがいいです

2012-12-26 16:49:55
Kenji Yoshida @xuwei_k

StreamやListは片方向リンクリストだから、結合や(tailを呼ぶだけの分割)などが多い場合は共有する部分多くてメモリ節約になるけど、そういう操作しないなら単にArrayかBufferにしたほうがポインタの分メモリ食わないからそのほうがいい(って別にScalaに限らないか

2012-12-26 17:03:18

これもオススメ

まとめ #Scala のStreamとIterator 7683 pv 25 6 users 3