(ベターオブジェクト指向言語からの脱皮)
- 参照透過性
- 再帰
- ストリーム
- 遅延評価
- ハードウェア:メニーコア化・大容量メモリ・SSD
- プラットフォーム:IoT・ビッグデータ・インメモリDB
メニーコアをちゃんとつかうには?
- 並列プログラミングの必然性
- 手続き型言語では難しい
- 並列とは、一つの作業を複数に分割して、それぞれを同時に実行する
- 並行とは、複数の作業を別々のスレッドで(同期をとりながら)実行する
- 並列処理:ストリームAPI
- 並行処理:アクターモデル(akka等)
- スレッド指向:スレッドの作成・スレッドプールは自作
- タスク指向:システムにスレッド生成をまかせる
- OOP:データはオブジェクト、メッセージはメソッド
- FP:データは不変、データに関数を適用し新しいデータを作る
制約プログラミング:プログラマに制約をかけ、自由度を減らす(破壊的代入・副作用・ループ)ことにより品質を上げる
動作保証された小さな関数を合成して新たな関数を作成する
- Curry-Howard同型対応:直観主義命題論理と単純肩付きラムダ計算の対応
- 関数の引数が同じなら戻り値は同じ
- 並列化しやすい
Javaでどう実践するのか
- メソッドは副作用がないように書く
- final宣言
- Immutableなオブジェクトを作成・使用
- mutableなクラスを安全に synchronized + mutable なデータ構造は clone を返す or java.util.concurrent.CopyOnWriteを使う or readonlyリストを返す
- 深い再帰stackoverflow -> JITは末尾再帰最適化未対応(ストリームで頑張る)
- parallelを付けるだけで並列化できる
- 無駄な処理をしなくてよくなる・重い処理を後回しにする・並列処理効率を上げられる
- メモリ使用量が増える・デバッグが難しくなる
- Stream APIの中間操作は遅延評価
- sequential()で並列から逐次に
- リダクションが並列にできるものと、できないものがある
- fork/joinのほうが早いが、スレッド数を上げるとStream APIとの差は収束傾向