SlideShare a Scribd company logo
1 of 57
Copyright 2015 FUJITSU LIMITED
[3-1]
Javaの関数型言語への挑戦/
ベターオブジェクト指向言語からの脱皮
2015年4月8日
富士通株式会社
数村 憲治
Java Day Tokyo 2015
Copyright 2015 FUJITSU LIMITED
 関数型言語とは
 Javaと関数型言語
 関数型言語の特徴
参照透過性
再帰
ストリーム
遅延評価
 ストリームで注意すべきこと
 Javaにおける並列プログラミングの実力
アジェンダ
1
関数型言語(FP)とは
Copyright 2015 FUJITSU LIMITED
Haskell
Scala
Erlang
F#
Lisp
無名関数
遅延評価
末尾再帰
高階関数
参照透過性
モナド
2
なぜ、今、関数型言語か
Copyright 2015 FUJITSU LIMITED
ハードウェア
メニーコア
大容量メモリ
SSD
並列プログラミングの
必然性
関数型言語に注目
手続き型言語では難しいIoT
ビッグデータ
インメモリデータベース
環境・プラットフォーム
3
メニーコアで性能向上させるには
Copyright 2015 FUJITSU LIMITED
プログラマーは、どれだけ頑張ればよいのか?
並列処理は、どんな言語でも頑張ればできる。
低い高い
熟練プログラマ
手続き型言語
熟練プログラマ
関数型言語
一般プログラマ
関数型言語
一般プログラマ
手続き型言語
性能+品質
≧
≫
4
≒
並列と並行
Copyright 2015 FUJITSU LIMITED
並列(Parallel)とは、
一つの作業を複数に分割し、
それぞれを「本当に」同時に実行することで、
全体処理時間を短くする。
並行(Concurrent)とは、
複数の作業を別々のスレッドで、
(同期を取りながら)実行する。
必ずしも「本当に」同時に実行しなくてもよい。
5
並列と並行の例
Copyright 2015 FUJITSU LIMITED
Parallel GC
Concurrent GC
GC thread #1
GC thread #2
GC thread #3
GC処理を
複数スレッドで
同時に実行
GC thread
APP thread #1
APP thread #2
GC処理とアプリ処理を
同時に実行
6
並行・並列プログラミングレベル
Copyright 2015 FUJITSU LIMITED
レベル1 レベル2 レベル3
スレッド生成・終了 アプリ 言語システム 言語システム
排他制御 アプリ 言語システム 言語システム
スレッドプール管理 アプリ 言語システム 言語システム
タスク指向
fork/join・future
なし アプリ 言語システム
Actorモデル なし なし アプリ
ストリーミング なし なし アプリ
C/C++
Java SE 5-7
FP
Java SE 1.4 Java SE 8
7
レベル1からレベル2へ
Copyright 2015 FUJITSU LIMITED
スレッド指向
・スレッドを作るところから始める
・スレッドから子スレッドを作ると収集つかない
・スレッドプールは自作
タスク指向
・スレッドの生成やプーリングはシステムで
・プログラマは、スレッドで行う仕事にフォーカス
・結果を同期、非同期いずれでも確認可能
8
スレッド指向とタスク指向
Copyright 2015 FUJITSU LIMITED
スレッド指向 タスク指向
class Target
implements Runnable
{
public void run() {
// do something
}
}
Target target = new Target();
Thread t1 =
new Thread(target);
t1.start();
t1.join();
result = target.get();
class Task
extends RecursiveTask <Object>
{
Object compute() {
// do something
}
}
ForkJoinPool pool =
new ForkJoinPool(N);
Future future =
pool.submit(new Task());
if (future.isDone())
result = future.get();
9
レベル2からレベル3へ
Copyright 2015 FUJITSU LIMITED
アクターモデル
akka等
Javaの標準ライブラリには含まれていない
レベル2 レベル3
ストリームAPI
並列処理
並行処理
10
Copyright 2015 FUJITSU LIMITED
 関数型言語とは
 Javaと関数型言語
 関数型言語の特徴
参照透過性
再帰
ストリーム
遅延評価
 ストリームで注意すべきこと
 Javaにおける並列プログラミングの実力
アジェンダ
11
パラダイムシフト
Copyright 2015 FUJITSU LIMITED
命令型 オブジェクト指向 関数型
C C++ HaskellScalaJava
ベターC
ベターOOP
?
?
?
継承
カプセル化
・・・
参照透過
ラムダ
・・・
モジュール
構造化
・・・
12
Javaはどこへ向かうのか
Copyright 2015 FUJITSU LIMITED
It is my belief that the best direction for evolving Java
is to encourage a more functional style of
programming. The role of Lambda is primarily to
support the development and consumption of more
functional-like libraries; I've offered examples such as
filter-map-reduce to illustrate this direction.
Simply put, we believe the best thing we can do for Java
developers is to give them a gentle push towards a more
functional style of programming. We're not going to
turn Java into Haskell, nor even into Scala.
http://mail.openjdk.java.net/pipermail/lambda-dev/2011-August/003877.html
Brian Goetz
13
OOPとFP
Copyright 2015 FUJITSU LIMITED
・データはオブジェクト。メッセージはメソッド。
・オブジェクトにメッセージを送り状態を変化。
OOP
FP ・データは不変。
・データに関数を適用し、新しいデータを作る。
データ(オブジェクト)
1 → 3 → 9
データ:1 データ:3 データ:9
メッセージ: +2
メッセージ: X3
関数: +2 関数: X3
14
FP品質 - 制約プログラミング
Copyright 2015 FUJITSU LIMITED
関数型言語で新たに出来ることよりも、
オブジェクト指向言語で出来たことが、
関数型言語では出来なくなることが重要。
破壊的代入 副作用
プログラマに制約をかけ、自由度を減らす
ループ
プログラム品質の向上
15
FP品質 - 数学的プログラミング
Copyright 2015 FUJITSU LIMITED
証明された定理を積み上げて
新たな定理を証明
動作保証された小さな関数を合成して
新たな関数を作成
コンパイルが通れば動作の証明(型に関して)
数学
Curry-Howard同型対応
プログラム
命題=型 証明=プログラム
直感主義命題論理と単純型付ラムダ計算の対応
16
Copyright 2015 FUJITSU LIMITED
 関数型言語とは
 Javaと関数型言語
 関数型言語の特徴
参照透過性
再帰
ストリーム
遅延評価
 ストリームで注意すべきこと
 Javaにおける並列プログラミングの実力
アジェンダ
17
参照透過性
Copyright 2015 FUJITSU LIMITED
Javaのメソッド
関数型言語の関数
・関数の引数が同じなら、戻り値は同じ
・関数呼び出しによる副作用(状態変化)なし
→ 並列化しやすい
・メソッド呼び出しは、メッセージ送信
・メソッドはオブジェクトの状態を変化させる
→ 並列化しにくい
・変数の再代入(破壊的代入)ができない
18
Javaで参照透過を実現するには
19 Copyright 2015 FUJITSU LIMITED
・メソッドは副作用がないように書く。
・変数には、「final」をつける。
・Immutableオブジェクトを作成・使用。
→ できる範囲で
Immutableオブジェクト
Copyright 2015 FUJITSU LIMITED
char* str = ・・・
str[3] = ‘0’;
String str = ・・・
str = str.substring(3);
Cプログラム
Javaプログラム
オーバランの危険性
Stringはimmutable
常に新しいString生成
複数スレッドで操作すると
データ破壊の可能性
ImmutableなStringがJavaを高品質に
20
Mutableなクラス
Copyright 2015 FUJITSU LIMITED
public class SuperMarket {
private ArrayList<Food> foodList;
public List<Food> get() {
return foodList;
}
public void add(Food food) {
foodList.add(food);
}
public void remove(Food food) {
foodList.remove(food);
}
複数スレッドから
呼べない
mutable
安全にするには?(並行プログラミング)
21
mutableなクラスを安全に
Copyright 2015 FUJITSU LIMITED
public class SuperMarket {
private ArrayList<Food> foodList;
public synchronized List<Food> get() {
return foodList;
}
public synchronized void add(Food food) {
foodList.add(food);
}
public synchronized void remove(Food food) {
foodList.remove(food);
}
getメソッドで返されるListオブジェクトがmutable
22
mutableなクラスを安全に
Copyright 2015 FUJITSU LIMITED
public class SuperMarket {
private ArrayList<Food> foodList;
public synchronized List<Food> get() {
return foodList.clone();
}
public synchronized void add(Food food) {
foodList.add(food);
}
public synchronized void remove(Food food) {
foodList.remove(food);
}
23
更新があまりないなら
Copyright 2015 FUJITSU LIMITED
public class SuperMarket {
private CopyOnWriteArrayList<Food> foodList;
public synchronized List<Food> get() {
return foodList.clone();
}
public synchronized void add(Food food) {
foodList.add(food);
}
public synchronized void remove(Food food) {
foodList.remove(food);
}
java.util.concurrent.CopyOnWriteArrayListの使用で
synchronizedを削減
24
Listを更新されたくないなら
Copyright 2015 FUJITSU LIMITED
public class SuperMarket {
private CopyOnWriteArrayList<Food> foodList;
public List<Food> get() {
return
Collections.unmodifiableList(
foodList.clone());
}
java.util.Collections.unmodifiableListで
read-onlyのListの作成
25
Copyright 2015 FUJITSU LIMITED
 関数型言語とは
 Javaと関数型言語
 関数型言語の特徴
参照透過性
再帰
ストリーム
遅延評価
 ストリームで注意すべきこと
 Javaにおける並列プログラミングの実力
アジェンダ
26
ループから再帰
Copyright 2015 FUJITSU LIMITED
int foo(Bar[] bars) {
int result = 0;
for (int i = 0 ; i < bars.length ; ++i)
result += bars[i].get();
return result;
}
int foo(final Bar[] bars) {
return foo1(0, 0, bars);
}
int foo1(final int n, final int result, final Bar[] bars) {
if (n == bars.length)
return result;
return foo1(n+1, bars[n].get()+result, bars);
}
ループ
再帰
再代入の解消
27
末尾再帰最適化(TCO)
Copyright 2015 FUJITSU LIMITED
Java(JIT)では未対応
最後の処理が自分自身への呼び出しなら、
関数コール(新しいスタック作成)しない。
ループ処理のように同じスタックで処理する。
int foo1(final int n, final int result, final Bar[] bars) {
if (n == bars.length)
return result;
return foo1(n+1, bars[n].get()+result, bars);
}
最後の処理が
自分自身への
呼び出し
28
Copyright 2015 FUJITSU LIMITED
 関数型言語とは
 Javaと関数型言語
 関数型言語の特徴
参照透過性
再帰
ストリーム
遅延評価
 ストリームで注意すべきこと
 Javaにおける並列プログラミングの実力
アジェンダ
29
ストリーム(パイプライン)とは
Copyright 2015 FUJITSU LIMITED
UNIXのパイプ処理
% cat input | grep keyword | sort | head -5 > output
read(input).stream()
.filter(keyword)
.sorted()
.limit(5)
.writeTo(output)
ストリームプログラミング
30
FPスタイル
input func1 func2 func3 output
ループからストリーム
Copyright 2015 FUJITSU LIMITED
Java SE 7の
糖衣構文
int foo(Bar[] bars) {
int result = 0;
for (int i = 0 ; i < bars.length ; ++i)
result += bars[i].get();
int foo(Bar[] bars) {
int result = 0;
for (Bar b : bars)
result += b.get();
int foo(Bar[] bars) {
return Arrays.stream(bars)
.mapToInt( b -> b.get() );
.sum();
Java SE 8の
stream API
31
ループv.s.ストリーム(並列化)
Copyright 2015 FUJITSU LIMITED
int foo(Bar[] bars) throws InterruptedException {
BarSum[] barSum = new BarSum[N];
for (int i = 0 ; i < N ; ++i)
barSum[i] = new BarSum(bars, bars.length/N*i,
bars.length/N*(i+1));
int result = 0;
for (int i = 0 ; i < N ; ++i) {
barSum[i].join();
result += barSum[i].result;
}
return result;
}
class BarSum extends Thread {
Bar[] bars;
int begin, end;
int result;
BarSum(Bar[] bars, int begin, int end) {
this.bars = bars;
this.begin = begin;
this.end = end;
}
public void run() {
for (int i = begin ; i < end ; ++i)
result += bars[i].get();
}
}
ループの並列化
int foo(Bar[] bars) {
return Arrays.stream(bars)
.parallel()
.mapToInt( b -> b.get() );
.sum();
ストリームの並列化
32
Copyright 2015 FUJITSU LIMITED
 関数型言語とは
 Javaと関数型言語
 関数型言語の特徴
参照透過性
再帰
ストリーム
遅延評価
 ストリームで注意すべきこと
 Javaにおける並列プログラミングの実力
アジェンダ
33
遅延評価
Copyright 2015 FUJITSU LIMITED
デメリット
・メモリ使用量が増える
・デバッグが難しくなる
必要になるまで評価しない
メリット
・無駄な処理をしなくてよくなる
・重い処理を後回しにできる
・並列処理効率を上げられる
34
Javaでの評価タイミング
Copyright 2015 FUJITSU LIMITED
nの値はここで決定
if ( f1() && f2() ) { f1()がfalseならf2()は評価しない
int n = foo();
// nに関係ない処理
System.out.println(n);
一般的には遅延評価と言わない
例1
例2
ここなら
遅延評価という
Javaでは
普通のメソッド呼び出しは遅延評価しない
35
Javaにおける遅延評価
Copyright 2015 FUJITSU LIMITED
ストリームの中間操作は遅延評価
終端操作実行時に評価
int foo(List<Integer> list) {
return list.stream()
.filter(i -> i > 30)
.mapToInt(i -> i * 2)
.limit(50)
.sum();
}
中間操作
中間操作
終端操作
中間操作
36
ストリーム操作の種類
Copyright 2015 FUJITSU LIMITED
ストリーム操作
ステートフル操作
distinct/sorted
ステートレス操作
map/filter
終端操作
forEach/count
中間操作
遅延評価
並列化しやすい
37
多段ループ処理
Copyright 2015 FUJITSU LIMITED
int foo(List<Integer> list) {
ArrayList<Integer> list2 = new ArrayList<>;
for (int i : list)
if (i > 30) list2.add(i);
ArrayList<Integer> list3 = new ArrayList<>;
for (int i : list2) list3.add(i * 2)
int result = 0; int count = 0;
for (int i : list3) {
result += i;
count ++;
if (count == 50)
break;
}
return result;
待ち合わせ
待ち合わせ
38
メニーコアにおける並列化
Copyright 2015 FUJITSU LIMITED
コア1理想
現実 コア2
コア2
コアn
コアn
コア1
タスク
タスク
タスク
タスク タスクタスク
タスク タスク
タスク
タスク
タスク
タスク
タスク
タスク
・・・
同時に終わる
タスク
タスク
タスク
タスク
空き
空き
・・・
CPUに空き
39
ループの並列処理化
Copyright 2015 FUJITSU LIMITED
int foo(List<Integer> list) {
int result = 0;
int count = 0;
for (int i : list) {
if (i > 30) {
result += i *2;
count ++;
if (count == 50)
break;
}
}
return result;
}
複数スレッドで
同期を取りながら
50数える必要がある
ループは一つになったが
並列化するには、
40
遅延評価と並列化
Copyright 2015 FUJITSU LIMITED
int foo(List<Integer> list) {
return list.stream()
.parallel()
.filter(i -> i > 30)
.mapToInt(i -> i * 2)
.limit(50)
.sum();
}
待ち合わせ
待ち合わせ
待ち合わせ
遅延評価がないと
並列化の源は遅延評価
41
Copyright 2015 FUJITSU LIMITED
 関数型言語とは
 Javaと関数型言語
 関数型言語の特徴
参照透過性
再帰
ストリーム
遅延評価
 ストリームで注意すべきこと
 Javaにおける並列プログラミングの実力
アジェンダ
42
並列から逐次へ
Copyright 2015 FUJITSU LIMITED
ソート後は逐次に
someStream
.parallel()
.filter(e -> e.shouldHandle())
.sorted()
.limit(100)
.forEach(e -> System.out.println(e));
someStream
.parallel()
.filter(e -> e.shouldHandle())
.sorted()
.sequential()
.limit(100)
.forEach(e -> System.out.println(e));
ソートされない
出力
43
streamは速やかに流す
Copyright 2015 FUJITSU LIMITED
Synchronizedを使わない
static Object lock = new Object();
Bar foo(List<Bar> list) {
return list.stream()
.parallel()
.map(b -> {
synchronized (lock) { return b.baz();}
})
.max(comparator);
}
44
副作用を書かない
Copyright 2015 FUJITSU LIMITED
void foo(List<Bar> list) {
ArrayList<Bar> result = new ArrayList<>();
list.stream()
.parallel()
.filter(b -> b.baz())
.forEach(b -> result.add(b));
List<Bar> result = list.stream()
.parallel()
.filter(b -> b.baz())
.collect(Collectors.toList());
45
Collectors(リダクション)
Copyright 2015 FUJITSU LIMITED
・リダクション用のstaticメソッド群が定義
・Stream.collect()メソッドに指定する
・toList/groupingBy/summingIntなど
例:
java.util.stream.Collectors
List<Bar> result = list.stream()
.parallel()
.filter(b -> b.baz())
.collect(Collectors.toList());
46
CollectorとStreamの属性
Copyright 2015 FUJITSU LIMITED
UNORDERED: 順序が保証されない
IDENTITY_FINISH: フィニッシャー不要
CONCURRENT: アキュムレータの同時呼び出し可
Collectorの属性
Streamの属性
unordered: 順序不定のストリーム
parallel: 並列ストリーム
47
並列リダクションの条件
Copyright 2015 FUJITSU LIMITED
(A) Streamがparallel
かつ
(B) CollectorがCONCURRENT
かつ
(C) Streamがunordered または
CollectorがUNORDERED
48
並列リダクション
Copyright 2015 FUJITSU LIMITED
Map<Foo, Bar> result = source.stream()
.parallel()
.filter(b -> b.baz())
.collect(toMap(b->b.foo(), b));
ConcurrentMap<Foo, Bar> result =
source.stream()
.parallel()
.filter(b -> b.baz())
.collect(toConcurrentMap(b->b.foo(), b));
非並列
並列
CONCURRENT属性なし
CONCURRENT属性
UNORDERED属性
49
parallel stream
parallel stream
Copyright 2015 FUJITSU LIMITED
 関数型言語とは
 Javaと関数型言語
 関数型言語の特徴
参照透過性
再帰
ストリーム
遅延評価
 ストリームで注意すべきこと
 Javaにおける並列プログラミングの実力
アジェンダ
50
Stream APIによる並列性能
Copyright 2015 FUJITSU LIMITED
レベル2のプログラム(fork/join使用)と
レベル3のプログラム(stream使用)との比較
ベンチマークモデル
100万件の購買伝票を基に、
購入関連の高い商品群を抽出し、
未購入ユーザにレコメンドする。
指標
生産性(ソース行数)と性能(実行時間)
51
生産性(ソース行数)
Copyright 2015 FUJITSU LIMITED
static Map<Account, List<Product>> createProductMap(Account[] accounts) {
return Arrays.stream(accounts).parallel()
.collect(Collectors.toMap(Function.identity(),
acc -> acc.records.stream()
.flatMap(rec -> rec.orders.stream())
.map(ord -> ord.product)
.distinct()
.collect(Collectors.toList())));
}
static Map<Account, List<Product>> createProductMap(Account[] accounts) {
Map<Account, List<Product>> map = new ConcurrentHashMap<>();
ArrayList<ForkJoinTask> tlist = new ArrayList<>();
for (Account acc : accounts) {
ForkJoinTask task = pool.submit(new Runnable() {
public void run() {
ArrayList<Product> list = new ArrayList<>();
for (PurchaseRecord pr : acc.records)
for (Order ord : pr.orders)
if (!list.contains(ord.product))
list.add(ord.product);
map.put(acc, list);
}});
tlist.add(task);
}
for (ForkJoinTask task : tlist)
task.join();
return map;
}
レベル2のソース レベル3のソース
0
20
40
60
80
100
120
140
レベル2(fork/join) レベル3(stream)
ス
テ
ッ
プ
数
ソース行数(除共通部分)
52
性能(処理時間)
Copyright 2015 FUJITSU LIMITED
M10-4S SPARC64-X 4CPU x16core x2thread
・スレッド数が少ないほど、レベル2の方が良い
・スレッド数が大きくなると、差はほとんどなくなる傾向
0
5000
10000
15000
20000
25000
30000
35000
40000
2 4 8 16 32 64 128
時
間
(
m
s
)
スレッド数
レベル2(fork/join)
レベル3(stream)
53
まとめ
54 Copyright 2015 FUJITSU LIMITED
オブジェクト指向言語
Javaによる高品質並列処理
関数型言語の仕組みを知る
メニーコアを使い切る並列プログラミング
ストリームプログラミング
参照透過・遅延評価の活用
Q&A
Copyright 2015 FUJITSU LIMITED55
Copyright 2010 FUJITSU LIMITED

More Related Content

What's hot

Xtend30分クッキング やきに駆動
Xtend30分クッキング   やきに駆動Xtend30分クッキング   やきに駆動
Xtend30分クッキング やきに駆動Shinichi Kozake
 
Java One 2012 Tokyo JVM Lang. BOF(Groovy)
Java One 2012 Tokyo JVM Lang. BOF(Groovy)Java One 2012 Tokyo JVM Lang. BOF(Groovy)
Java One 2012 Tokyo JVM Lang. BOF(Groovy)Uehara Junji
 
モナドハンズオン前座
モナドハンズオン前座モナドハンズオン前座
モナドハンズオン前座bleis tift
 
yieldとreturnの話
yieldとreturnの話yieldとreturnの話
yieldとreturnの話bleis tift
 
Pythonと型チェッカー
Pythonと型チェッカーPythonと型チェッカー
Pythonと型チェッカーTetsuya Morimoto
 
【DELPHI / C++BUILDER STARTER チュートリアルシリーズ】 シーズン2 Delphi の部 第5回 「配列 と レコード 」
【DELPHI / C++BUILDER STARTER チュートリアルシリーズ】 シーズン2 Delphi の部 第5回 「配列 と レコード 」【DELPHI / C++BUILDER STARTER チュートリアルシリーズ】 シーズン2 Delphi の部 第5回 「配列 と レコード 」
【DELPHI / C++BUILDER STARTER チュートリアルシリーズ】 シーズン2 Delphi の部 第5回 「配列 と レコード 」Kaz Aiso
 
すごいConstたのしく使おう!
すごいConstたのしく使おう!すごいConstたのしく使おう!
すごいConstたのしく使おう!Akihiro Nishimura
 
Python と型ヒント (Type Hints)
Python と型ヒント (Type Hints)Python と型ヒント (Type Hints)
Python と型ヒント (Type Hints)Tetsuya Morimoto
 
マルチコアを用いた画像処理
マルチコアを用いた画像処理マルチコアを用いた画像処理
マルチコアを用いた画像処理Norishige Fukushima
 
JJavaプログラム実行の仕組みと、高速・安定動作に向けた取り組み
JJavaプログラム実行の仕組みと、高速・安定動作に向けた取り組みJJavaプログラム実行の仕組みと、高速・安定動作に向けた取り組み
JJavaプログラム実行の仕組みと、高速・安定動作に向けた取り組み日本Javaユーザーグループ
 
エラーハンドリング
エラーハンドリングエラーハンドリング
エラーハンドリング道化師 堂華
 

What's hot (12)

Xtend30分クッキング やきに駆動
Xtend30分クッキング   やきに駆動Xtend30分クッキング   やきに駆動
Xtend30分クッキング やきに駆動
 
Java One 2012 Tokyo JVM Lang. BOF(Groovy)
Java One 2012 Tokyo JVM Lang. BOF(Groovy)Java One 2012 Tokyo JVM Lang. BOF(Groovy)
Java One 2012 Tokyo JVM Lang. BOF(Groovy)
 
モナドハンズオン前座
モナドハンズオン前座モナドハンズオン前座
モナドハンズオン前座
 
yieldとreturnの話
yieldとreturnの話yieldとreturnの話
yieldとreturnの話
 
Pythonと型チェッカー
Pythonと型チェッカーPythonと型チェッカー
Pythonと型チェッカー
 
【DELPHI / C++BUILDER STARTER チュートリアルシリーズ】 シーズン2 Delphi の部 第5回 「配列 と レコード 」
【DELPHI / C++BUILDER STARTER チュートリアルシリーズ】 シーズン2 Delphi の部 第5回 「配列 と レコード 」【DELPHI / C++BUILDER STARTER チュートリアルシリーズ】 シーズン2 Delphi の部 第5回 「配列 と レコード 」
【DELPHI / C++BUILDER STARTER チュートリアルシリーズ】 シーズン2 Delphi の部 第5回 「配列 と レコード 」
 
すごいConstたのしく使おう!
すごいConstたのしく使おう!すごいConstたのしく使おう!
すごいConstたのしく使おう!
 
Python と型ヒント (Type Hints)
Python と型ヒント (Type Hints)Python と型ヒント (Type Hints)
Python と型ヒント (Type Hints)
 
マルチコアを用いた画像処理
マルチコアを用いた画像処理マルチコアを用いた画像処理
マルチコアを用いた画像処理
 
JJavaプログラム実行の仕組みと、高速・安定動作に向けた取り組み
JJavaプログラム実行の仕組みと、高速・安定動作に向けた取り組みJJavaプログラム実行の仕組みと、高速・安定動作に向けた取り組み
JJavaプログラム実行の仕組みと、高速・安定動作に向けた取り組み
 
Effective Java 輪読会 項目45-48
Effective Java 輪読会 項目45-48Effective Java 輪読会 項目45-48
Effective Java 輪読会 項目45-48
 
エラーハンドリング
エラーハンドリングエラーハンドリング
エラーハンドリング
 

Viewers also liked

Challenge for GlassFish Builpack
Challenge for GlassFish BuilpackChallenge for GlassFish Builpack
Challenge for GlassFish BuilpackKenji Kazumura
 
Versatil Javaチューニング
Versatil JavaチューニングVersatil Javaチューニング
Versatil JavaチューニングKenji Kazumura
 
Python + GDB = Javaデバッガ
Python + GDB = JavaデバッガPython + GDB = Javaデバッガ
Python + GDB = JavaデバッガKenji Kazumura
 
Javaでトランザクショナルメモリを使う
Javaでトランザクショナルメモリを使うJavaでトランザクショナルメモリを使う
Javaでトランザクショナルメモリを使うKenji Kazumura
 

Viewers also liked (6)

Challenge for GlassFish Builpack
Challenge for GlassFish BuilpackChallenge for GlassFish Builpack
Challenge for GlassFish Builpack
 
Versatil Javaチューニング
Versatil JavaチューニングVersatil Javaチューニング
Versatil Javaチューニング
 
CPUから見たG1GC
CPUから見たG1GCCPUから見たG1GC
CPUから見たG1GC
 
Python + GDB = Javaデバッガ
Python + GDB = JavaデバッガPython + GDB = Javaデバッガ
Python + GDB = Javaデバッガ
 
microprofile
microprofilemicroprofile
microprofile
 
Javaでトランザクショナルメモリを使う
Javaでトランザクショナルメモリを使うJavaでトランザクショナルメモリを使う
Javaでトランザクショナルメモリを使う
 

Similar to JavaDayTokyo2015 [3-1]

Groovy Bootcamp 2015 by JGGUG
Groovy Bootcamp 2015 by JGGUGGroovy Bootcamp 2015 by JGGUG
Groovy Bootcamp 2015 by JGGUGUehara Junji
 
from old java to java8 - KanJava Edition
from old java to java8 - KanJava Editionfrom old java to java8 - KanJava Edition
from old java to java8 - KanJava Edition心 谷本
 
New features of Groovy 2.0 and 2.1
New features of Groovy 2.0 and 2.1New features of Groovy 2.0 and 2.1
New features of Groovy 2.0 and 2.1Uehara Junji
 
【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第6回 ‟文字列とオブジェクト„
【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第6回 ‟文字列とオブジェクト„【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第6回 ‟文字列とオブジェクト„
【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第6回 ‟文字列とオブジェクト„和弘 井之上
 
Java Puzzlers JJUG CCC 2016
Java Puzzlers JJUG CCC 2016Java Puzzlers JJUG CCC 2016
Java Puzzlers JJUG CCC 2016Yoshio Terada
 
【java8 勉強会】 怖くない!ラムダ式, Stream API
【java8 勉強会】 怖くない!ラムダ式, Stream API【java8 勉強会】 怖くない!ラムダ式, Stream API
【java8 勉強会】 怖くない!ラムダ式, Stream APIdcomsolution
 
Angular ユーザーなら押さえておきたい! TypeScript と Visual Studio Code の基礎と活用
Angular ユーザーなら押さえておきたい! TypeScript と Visual Studio Code の基礎と活用Angular ユーザーなら押さえておきたい! TypeScript と Visual Studio Code の基礎と活用
Angular ユーザーなら押さえておきたい! TypeScript と Visual Studio Code の基礎と活用Akira Inoue
 
Head toward Java 15 and Java 16
Head toward Java 15 and Java 16Head toward Java 15 and Java 16
Head toward Java 15 and Java 16Yuji Kubota
 
第三回ありえる社内勉強会 「いわががのLombok」
第三回ありえる社内勉強会 「いわががのLombok」第三回ありえる社内勉強会 「いわががのLombok」
第三回ありえる社内勉強会 「いわががのLombok」yoshiaki iwanaga
 
"今" 押さえておきたい! Web アプリ開発の技術トレンドとツールの進化
"今" 押さえておきたい! Web アプリ開発の技術トレンドとツールの進化"今" 押さえておきたい! Web アプリ開発の技術トレンドとツールの進化
"今" 押さえておきたい! Web アプリ開発の技術トレンドとツールの進化Akira Inoue
 
JDK 10 へようこそ
JDK 10 へようこそJDK 10 へようこそ
JDK 10 へようこそDavid Buck
 
Javaセキュアコーディングセミナー東京第3回講義
Javaセキュアコーディングセミナー東京第3回講義Javaセキュアコーディングセミナー東京第3回講義
Javaセキュアコーディングセミナー東京第3回講義JPCERT Coordination Center
 
【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第4回 ‟関数„
【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第4回 ‟関数„【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第4回 ‟関数„
【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第4回 ‟関数„和弘 井之上
 
GNU awk (gawk) を用いた Apache ログ解析方法
GNU awk (gawk) を用いた Apache ログ解析方法GNU awk (gawk) を用いた Apache ログ解析方法
GNU awk (gawk) を用いた Apache ログ解析方法博文 斉藤
 
ゆるふわJava8入門
ゆるふわJava8入門ゆるふわJava8入門
ゆるふわJava8入門dcubeio
 
DEV-011_TypeScript ~Any browser. Any host. Any OS. Open Source~
DEV-011_TypeScript ~Any browser. Any host. Any OS. Open Source~DEV-011_TypeScript ~Any browser. Any host. Any OS. Open Source~
DEV-011_TypeScript ~Any browser. Any host. Any OS. Open Source~decode2016
 
Quarkus による超音速な Spring アプリケーション開発
Quarkus による超音速な Spring アプリケーション開発Quarkus による超音速な Spring アプリケーション開発
Quarkus による超音速な Spring アプリケーション開発Chihiro Ito
 
Java仮想マシンの実装技術
Java仮想マシンの実装技術Java仮想マシンの実装技術
Java仮想マシンの実装技術Kiyokuni Kawachiya
 
Introduction to WildFly Swarm
Introduction to WildFly SwarmIntroduction to WildFly Swarm
Introduction to WildFly SwarmYoshimasa Tanabe
 

Similar to JavaDayTokyo2015 [3-1] (20)

Groovy Bootcamp 2015 by JGGUG
Groovy Bootcamp 2015 by JGGUGGroovy Bootcamp 2015 by JGGUG
Groovy Bootcamp 2015 by JGGUG
 
from old java to java8 - KanJava Edition
from old java to java8 - KanJava Editionfrom old java to java8 - KanJava Edition
from old java to java8 - KanJava Edition
 
New features of Groovy 2.0 and 2.1
New features of Groovy 2.0 and 2.1New features of Groovy 2.0 and 2.1
New features of Groovy 2.0 and 2.1
 
【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第6回 ‟文字列とオブジェクト„
【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第6回 ‟文字列とオブジェクト„【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第6回 ‟文字列とオブジェクト„
【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第6回 ‟文字列とオブジェクト„
 
Java Puzzlers JJUG CCC 2016
Java Puzzlers JJUG CCC 2016Java Puzzlers JJUG CCC 2016
Java Puzzlers JJUG CCC 2016
 
【java8 勉強会】 怖くない!ラムダ式, Stream API
【java8 勉強会】 怖くない!ラムダ式, Stream API【java8 勉強会】 怖くない!ラムダ式, Stream API
【java8 勉強会】 怖くない!ラムダ式, Stream API
 
Angular ユーザーなら押さえておきたい! TypeScript と Visual Studio Code の基礎と活用
Angular ユーザーなら押さえておきたい! TypeScript と Visual Studio Code の基礎と活用Angular ユーザーなら押さえておきたい! TypeScript と Visual Studio Code の基礎と活用
Angular ユーザーなら押さえておきたい! TypeScript と Visual Studio Code の基礎と活用
 
Head toward Java 15 and Java 16
Head toward Java 15 and Java 16Head toward Java 15 and Java 16
Head toward Java 15 and Java 16
 
第三回ありえる社内勉強会 「いわががのLombok」
第三回ありえる社内勉強会 「いわががのLombok」第三回ありえる社内勉強会 「いわががのLombok」
第三回ありえる社内勉強会 「いわががのLombok」
 
"今" 押さえておきたい! Web アプリ開発の技術トレンドとツールの進化
"今" 押さえておきたい! Web アプリ開発の技術トレンドとツールの進化"今" 押さえておきたい! Web アプリ開発の技術トレンドとツールの進化
"今" 押さえておきたい! Web アプリ開発の技術トレンドとツールの進化
 
JDK 10 へようこそ
JDK 10 へようこそJDK 10 へようこそ
JDK 10 へようこそ
 
Javaセキュアコーディングセミナー東京第3回講義
Javaセキュアコーディングセミナー東京第3回講義Javaセキュアコーディングセミナー東京第3回講義
Javaセキュアコーディングセミナー東京第3回講義
 
【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第4回 ‟関数„
【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第4回 ‟関数„【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第4回 ‟関数„
【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第4回 ‟関数„
 
GNU awk (gawk) を用いた Apache ログ解析方法
GNU awk (gawk) を用いた Apache ログ解析方法GNU awk (gawk) を用いた Apache ログ解析方法
GNU awk (gawk) を用いた Apache ログ解析方法
 
ゆるふわJava8入門
ゆるふわJava8入門ゆるふわJava8入門
ゆるふわJava8入門
 
DEV-011_TypeScript ~Any browser. Any host. Any OS. Open Source~
DEV-011_TypeScript ~Any browser. Any host. Any OS. Open Source~DEV-011_TypeScript ~Any browser. Any host. Any OS. Open Source~
DEV-011_TypeScript ~Any browser. Any host. Any OS. Open Source~
 
Refactoring point of Kotlin application
Refactoring point of Kotlin applicationRefactoring point of Kotlin application
Refactoring point of Kotlin application
 
Quarkus による超音速な Spring アプリケーション開発
Quarkus による超音速な Spring アプリケーション開発Quarkus による超音速な Spring アプリケーション開発
Quarkus による超音速な Spring アプリケーション開発
 
Java仮想マシンの実装技術
Java仮想マシンの実装技術Java仮想マシンの実装技術
Java仮想マシンの実装技術
 
Introduction to WildFly Swarm
Introduction to WildFly SwarmIntroduction to WildFly Swarm
Introduction to WildFly Swarm
 

Recently uploaded

論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNetToru Tamaki
 
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Yuma Ohgami
 
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...博三 太田
 
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...Toru Tamaki
 
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdfAWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdfFumieNakayama
 
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)Hiroki Ichikura
 
TSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdfTSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdftaisei2219
 
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?akihisamiyanaga1
 
SOPを理解する 2024/04/19 の勉強会で発表されたものです
SOPを理解する       2024/04/19 の勉強会で発表されたものですSOPを理解する       2024/04/19 の勉強会で発表されたものです
SOPを理解する 2024/04/19 の勉強会で発表されたものですiPride Co., Ltd.
 
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineerYuki Kikuchi
 
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdfクラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdfFumieNakayama
 
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案sugiuralab
 
論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A surveyToru Tamaki
 
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)UEHARA, Tetsutaro
 

Recently uploaded (14)

論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet
 
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
 
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
 
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
 
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdfAWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
 
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
 
TSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdfTSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdf
 
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
 
SOPを理解する 2024/04/19 の勉強会で発表されたものです
SOPを理解する       2024/04/19 の勉強会で発表されたものですSOPを理解する       2024/04/19 の勉強会で発表されたものです
SOPを理解する 2024/04/19 の勉強会で発表されたものです
 
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
 
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdfクラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
 
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
 
論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey
 
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
 

JavaDayTokyo2015 [3-1]

  • 1. Copyright 2015 FUJITSU LIMITED [3-1] Javaの関数型言語への挑戦/ ベターオブジェクト指向言語からの脱皮 2015年4月8日 富士通株式会社 数村 憲治 Java Day Tokyo 2015
  • 2. Copyright 2015 FUJITSU LIMITED  関数型言語とは  Javaと関数型言語  関数型言語の特徴 参照透過性 再帰 ストリーム 遅延評価  ストリームで注意すべきこと  Javaにおける並列プログラミングの実力 アジェンダ 1
  • 3. 関数型言語(FP)とは Copyright 2015 FUJITSU LIMITED Haskell Scala Erlang F# Lisp 無名関数 遅延評価 末尾再帰 高階関数 参照透過性 モナド 2
  • 4. なぜ、今、関数型言語か Copyright 2015 FUJITSU LIMITED ハードウェア メニーコア 大容量メモリ SSD 並列プログラミングの 必然性 関数型言語に注目 手続き型言語では難しいIoT ビッグデータ インメモリデータベース 環境・プラットフォーム 3
  • 5. メニーコアで性能向上させるには Copyright 2015 FUJITSU LIMITED プログラマーは、どれだけ頑張ればよいのか? 並列処理は、どんな言語でも頑張ればできる。 低い高い 熟練プログラマ 手続き型言語 熟練プログラマ 関数型言語 一般プログラマ 関数型言語 一般プログラマ 手続き型言語 性能+品質 ≧ ≫ 4 ≒
  • 6. 並列と並行 Copyright 2015 FUJITSU LIMITED 並列(Parallel)とは、 一つの作業を複数に分割し、 それぞれを「本当に」同時に実行することで、 全体処理時間を短くする。 並行(Concurrent)とは、 複数の作業を別々のスレッドで、 (同期を取りながら)実行する。 必ずしも「本当に」同時に実行しなくてもよい。 5
  • 7. 並列と並行の例 Copyright 2015 FUJITSU LIMITED Parallel GC Concurrent GC GC thread #1 GC thread #2 GC thread #3 GC処理を 複数スレッドで 同時に実行 GC thread APP thread #1 APP thread #2 GC処理とアプリ処理を 同時に実行 6
  • 8. 並行・並列プログラミングレベル Copyright 2015 FUJITSU LIMITED レベル1 レベル2 レベル3 スレッド生成・終了 アプリ 言語システム 言語システム 排他制御 アプリ 言語システム 言語システム スレッドプール管理 アプリ 言語システム 言語システム タスク指向 fork/join・future なし アプリ 言語システム Actorモデル なし なし アプリ ストリーミング なし なし アプリ C/C++ Java SE 5-7 FP Java SE 1.4 Java SE 8 7
  • 9. レベル1からレベル2へ Copyright 2015 FUJITSU LIMITED スレッド指向 ・スレッドを作るところから始める ・スレッドから子スレッドを作ると収集つかない ・スレッドプールは自作 タスク指向 ・スレッドの生成やプーリングはシステムで ・プログラマは、スレッドで行う仕事にフォーカス ・結果を同期、非同期いずれでも確認可能 8
  • 10. スレッド指向とタスク指向 Copyright 2015 FUJITSU LIMITED スレッド指向 タスク指向 class Target implements Runnable { public void run() { // do something } } Target target = new Target(); Thread t1 = new Thread(target); t1.start(); t1.join(); result = target.get(); class Task extends RecursiveTask <Object> { Object compute() { // do something } } ForkJoinPool pool = new ForkJoinPool(N); Future future = pool.submit(new Task()); if (future.isDone()) result = future.get(); 9
  • 11. レベル2からレベル3へ Copyright 2015 FUJITSU LIMITED アクターモデル akka等 Javaの標準ライブラリには含まれていない レベル2 レベル3 ストリームAPI 並列処理 並行処理 10
  • 12. Copyright 2015 FUJITSU LIMITED  関数型言語とは  Javaと関数型言語  関数型言語の特徴 参照透過性 再帰 ストリーム 遅延評価  ストリームで注意すべきこと  Javaにおける並列プログラミングの実力 アジェンダ 11
  • 13. パラダイムシフト Copyright 2015 FUJITSU LIMITED 命令型 オブジェクト指向 関数型 C C++ HaskellScalaJava ベターC ベターOOP ? ? ? 継承 カプセル化 ・・・ 参照透過 ラムダ ・・・ モジュール 構造化 ・・・ 12
  • 14. Javaはどこへ向かうのか Copyright 2015 FUJITSU LIMITED It is my belief that the best direction for evolving Java is to encourage a more functional style of programming. The role of Lambda is primarily to support the development and consumption of more functional-like libraries; I've offered examples such as filter-map-reduce to illustrate this direction. Simply put, we believe the best thing we can do for Java developers is to give them a gentle push towards a more functional style of programming. We're not going to turn Java into Haskell, nor even into Scala. http://mail.openjdk.java.net/pipermail/lambda-dev/2011-August/003877.html Brian Goetz 13
  • 15. OOPとFP Copyright 2015 FUJITSU LIMITED ・データはオブジェクト。メッセージはメソッド。 ・オブジェクトにメッセージを送り状態を変化。 OOP FP ・データは不変。 ・データに関数を適用し、新しいデータを作る。 データ(オブジェクト) 1 → 3 → 9 データ:1 データ:3 データ:9 メッセージ: +2 メッセージ: X3 関数: +2 関数: X3 14
  • 16. FP品質 - 制約プログラミング Copyright 2015 FUJITSU LIMITED 関数型言語で新たに出来ることよりも、 オブジェクト指向言語で出来たことが、 関数型言語では出来なくなることが重要。 破壊的代入 副作用 プログラマに制約をかけ、自由度を減らす ループ プログラム品質の向上 15
  • 17. FP品質 - 数学的プログラミング Copyright 2015 FUJITSU LIMITED 証明された定理を積み上げて 新たな定理を証明 動作保証された小さな関数を合成して 新たな関数を作成 コンパイルが通れば動作の証明(型に関して) 数学 Curry-Howard同型対応 プログラム 命題=型 証明=プログラム 直感主義命題論理と単純型付ラムダ計算の対応 16
  • 18. Copyright 2015 FUJITSU LIMITED  関数型言語とは  Javaと関数型言語  関数型言語の特徴 参照透過性 再帰 ストリーム 遅延評価  ストリームで注意すべきこと  Javaにおける並列プログラミングの実力 アジェンダ 17
  • 19. 参照透過性 Copyright 2015 FUJITSU LIMITED Javaのメソッド 関数型言語の関数 ・関数の引数が同じなら、戻り値は同じ ・関数呼び出しによる副作用(状態変化)なし → 並列化しやすい ・メソッド呼び出しは、メッセージ送信 ・メソッドはオブジェクトの状態を変化させる → 並列化しにくい ・変数の再代入(破壊的代入)ができない 18
  • 20. Javaで参照透過を実現するには 19 Copyright 2015 FUJITSU LIMITED ・メソッドは副作用がないように書く。 ・変数には、「final」をつける。 ・Immutableオブジェクトを作成・使用。 → できる範囲で
  • 21. Immutableオブジェクト Copyright 2015 FUJITSU LIMITED char* str = ・・・ str[3] = ‘0’; String str = ・・・ str = str.substring(3); Cプログラム Javaプログラム オーバランの危険性 Stringはimmutable 常に新しいString生成 複数スレッドで操作すると データ破壊の可能性 ImmutableなStringがJavaを高品質に 20
  • 22. Mutableなクラス Copyright 2015 FUJITSU LIMITED public class SuperMarket { private ArrayList<Food> foodList; public List<Food> get() { return foodList; } public void add(Food food) { foodList.add(food); } public void remove(Food food) { foodList.remove(food); } 複数スレッドから 呼べない mutable 安全にするには?(並行プログラミング) 21
  • 23. mutableなクラスを安全に Copyright 2015 FUJITSU LIMITED public class SuperMarket { private ArrayList<Food> foodList; public synchronized List<Food> get() { return foodList; } public synchronized void add(Food food) { foodList.add(food); } public synchronized void remove(Food food) { foodList.remove(food); } getメソッドで返されるListオブジェクトがmutable 22
  • 24. mutableなクラスを安全に Copyright 2015 FUJITSU LIMITED public class SuperMarket { private ArrayList<Food> foodList; public synchronized List<Food> get() { return foodList.clone(); } public synchronized void add(Food food) { foodList.add(food); } public synchronized void remove(Food food) { foodList.remove(food); } 23
  • 25. 更新があまりないなら Copyright 2015 FUJITSU LIMITED public class SuperMarket { private CopyOnWriteArrayList<Food> foodList; public synchronized List<Food> get() { return foodList.clone(); } public synchronized void add(Food food) { foodList.add(food); } public synchronized void remove(Food food) { foodList.remove(food); } java.util.concurrent.CopyOnWriteArrayListの使用で synchronizedを削減 24
  • 26. Listを更新されたくないなら Copyright 2015 FUJITSU LIMITED public class SuperMarket { private CopyOnWriteArrayList<Food> foodList; public List<Food> get() { return Collections.unmodifiableList( foodList.clone()); } java.util.Collections.unmodifiableListで read-onlyのListの作成 25
  • 27. Copyright 2015 FUJITSU LIMITED  関数型言語とは  Javaと関数型言語  関数型言語の特徴 参照透過性 再帰 ストリーム 遅延評価  ストリームで注意すべきこと  Javaにおける並列プログラミングの実力 アジェンダ 26
  • 28. ループから再帰 Copyright 2015 FUJITSU LIMITED int foo(Bar[] bars) { int result = 0; for (int i = 0 ; i < bars.length ; ++i) result += bars[i].get(); return result; } int foo(final Bar[] bars) { return foo1(0, 0, bars); } int foo1(final int n, final int result, final Bar[] bars) { if (n == bars.length) return result; return foo1(n+1, bars[n].get()+result, bars); } ループ 再帰 再代入の解消 27
  • 29. 末尾再帰最適化(TCO) Copyright 2015 FUJITSU LIMITED Java(JIT)では未対応 最後の処理が自分自身への呼び出しなら、 関数コール(新しいスタック作成)しない。 ループ処理のように同じスタックで処理する。 int foo1(final int n, final int result, final Bar[] bars) { if (n == bars.length) return result; return foo1(n+1, bars[n].get()+result, bars); } 最後の処理が 自分自身への 呼び出し 28
  • 30. Copyright 2015 FUJITSU LIMITED  関数型言語とは  Javaと関数型言語  関数型言語の特徴 参照透過性 再帰 ストリーム 遅延評価  ストリームで注意すべきこと  Javaにおける並列プログラミングの実力 アジェンダ 29
  • 31. ストリーム(パイプライン)とは Copyright 2015 FUJITSU LIMITED UNIXのパイプ処理 % cat input | grep keyword | sort | head -5 > output read(input).stream() .filter(keyword) .sorted() .limit(5) .writeTo(output) ストリームプログラミング 30 FPスタイル input func1 func2 func3 output
  • 32. ループからストリーム Copyright 2015 FUJITSU LIMITED Java SE 7の 糖衣構文 int foo(Bar[] bars) { int result = 0; for (int i = 0 ; i < bars.length ; ++i) result += bars[i].get(); int foo(Bar[] bars) { int result = 0; for (Bar b : bars) result += b.get(); int foo(Bar[] bars) { return Arrays.stream(bars) .mapToInt( b -> b.get() ); .sum(); Java SE 8の stream API 31
  • 33. ループv.s.ストリーム(並列化) Copyright 2015 FUJITSU LIMITED int foo(Bar[] bars) throws InterruptedException { BarSum[] barSum = new BarSum[N]; for (int i = 0 ; i < N ; ++i) barSum[i] = new BarSum(bars, bars.length/N*i, bars.length/N*(i+1)); int result = 0; for (int i = 0 ; i < N ; ++i) { barSum[i].join(); result += barSum[i].result; } return result; } class BarSum extends Thread { Bar[] bars; int begin, end; int result; BarSum(Bar[] bars, int begin, int end) { this.bars = bars; this.begin = begin; this.end = end; } public void run() { for (int i = begin ; i < end ; ++i) result += bars[i].get(); } } ループの並列化 int foo(Bar[] bars) { return Arrays.stream(bars) .parallel() .mapToInt( b -> b.get() ); .sum(); ストリームの並列化 32
  • 34. Copyright 2015 FUJITSU LIMITED  関数型言語とは  Javaと関数型言語  関数型言語の特徴 参照透過性 再帰 ストリーム 遅延評価  ストリームで注意すべきこと  Javaにおける並列プログラミングの実力 アジェンダ 33
  • 35. 遅延評価 Copyright 2015 FUJITSU LIMITED デメリット ・メモリ使用量が増える ・デバッグが難しくなる 必要になるまで評価しない メリット ・無駄な処理をしなくてよくなる ・重い処理を後回しにできる ・並列処理効率を上げられる 34
  • 36. Javaでの評価タイミング Copyright 2015 FUJITSU LIMITED nの値はここで決定 if ( f1() && f2() ) { f1()がfalseならf2()は評価しない int n = foo(); // nに関係ない処理 System.out.println(n); 一般的には遅延評価と言わない 例1 例2 ここなら 遅延評価という Javaでは 普通のメソッド呼び出しは遅延評価しない 35
  • 37. Javaにおける遅延評価 Copyright 2015 FUJITSU LIMITED ストリームの中間操作は遅延評価 終端操作実行時に評価 int foo(List<Integer> list) { return list.stream() .filter(i -> i > 30) .mapToInt(i -> i * 2) .limit(50) .sum(); } 中間操作 中間操作 終端操作 中間操作 36
  • 38. ストリーム操作の種類 Copyright 2015 FUJITSU LIMITED ストリーム操作 ステートフル操作 distinct/sorted ステートレス操作 map/filter 終端操作 forEach/count 中間操作 遅延評価 並列化しやすい 37
  • 39. 多段ループ処理 Copyright 2015 FUJITSU LIMITED int foo(List<Integer> list) { ArrayList<Integer> list2 = new ArrayList<>; for (int i : list) if (i > 30) list2.add(i); ArrayList<Integer> list3 = new ArrayList<>; for (int i : list2) list3.add(i * 2) int result = 0; int count = 0; for (int i : list3) { result += i; count ++; if (count == 50) break; } return result; 待ち合わせ 待ち合わせ 38
  • 40. メニーコアにおける並列化 Copyright 2015 FUJITSU LIMITED コア1理想 現実 コア2 コア2 コアn コアn コア1 タスク タスク タスク タスク タスクタスク タスク タスク タスク タスク タスク タスク タスク タスク ・・・ 同時に終わる タスク タスク タスク タスク 空き 空き ・・・ CPUに空き 39
  • 41. ループの並列処理化 Copyright 2015 FUJITSU LIMITED int foo(List<Integer> list) { int result = 0; int count = 0; for (int i : list) { if (i > 30) { result += i *2; count ++; if (count == 50) break; } } return result; } 複数スレッドで 同期を取りながら 50数える必要がある ループは一つになったが 並列化するには、 40
  • 42. 遅延評価と並列化 Copyright 2015 FUJITSU LIMITED int foo(List<Integer> list) { return list.stream() .parallel() .filter(i -> i > 30) .mapToInt(i -> i * 2) .limit(50) .sum(); } 待ち合わせ 待ち合わせ 待ち合わせ 遅延評価がないと 並列化の源は遅延評価 41
  • 43. Copyright 2015 FUJITSU LIMITED  関数型言語とは  Javaと関数型言語  関数型言語の特徴 参照透過性 再帰 ストリーム 遅延評価  ストリームで注意すべきこと  Javaにおける並列プログラミングの実力 アジェンダ 42
  • 44. 並列から逐次へ Copyright 2015 FUJITSU LIMITED ソート後は逐次に someStream .parallel() .filter(e -> e.shouldHandle()) .sorted() .limit(100) .forEach(e -> System.out.println(e)); someStream .parallel() .filter(e -> e.shouldHandle()) .sorted() .sequential() .limit(100) .forEach(e -> System.out.println(e)); ソートされない 出力 43
  • 45. streamは速やかに流す Copyright 2015 FUJITSU LIMITED Synchronizedを使わない static Object lock = new Object(); Bar foo(List<Bar> list) { return list.stream() .parallel() .map(b -> { synchronized (lock) { return b.baz();} }) .max(comparator); } 44
  • 46. 副作用を書かない Copyright 2015 FUJITSU LIMITED void foo(List<Bar> list) { ArrayList<Bar> result = new ArrayList<>(); list.stream() .parallel() .filter(b -> b.baz()) .forEach(b -> result.add(b)); List<Bar> result = list.stream() .parallel() .filter(b -> b.baz()) .collect(Collectors.toList()); 45
  • 47. Collectors(リダクション) Copyright 2015 FUJITSU LIMITED ・リダクション用のstaticメソッド群が定義 ・Stream.collect()メソッドに指定する ・toList/groupingBy/summingIntなど 例: java.util.stream.Collectors List<Bar> result = list.stream() .parallel() .filter(b -> b.baz()) .collect(Collectors.toList()); 46
  • 48. CollectorとStreamの属性 Copyright 2015 FUJITSU LIMITED UNORDERED: 順序が保証されない IDENTITY_FINISH: フィニッシャー不要 CONCURRENT: アキュムレータの同時呼び出し可 Collectorの属性 Streamの属性 unordered: 順序不定のストリーム parallel: 並列ストリーム 47
  • 49. 並列リダクションの条件 Copyright 2015 FUJITSU LIMITED (A) Streamがparallel かつ (B) CollectorがCONCURRENT かつ (C) Streamがunordered または CollectorがUNORDERED 48
  • 50. 並列リダクション Copyright 2015 FUJITSU LIMITED Map<Foo, Bar> result = source.stream() .parallel() .filter(b -> b.baz()) .collect(toMap(b->b.foo(), b)); ConcurrentMap<Foo, Bar> result = source.stream() .parallel() .filter(b -> b.baz()) .collect(toConcurrentMap(b->b.foo(), b)); 非並列 並列 CONCURRENT属性なし CONCURRENT属性 UNORDERED属性 49 parallel stream parallel stream
  • 51. Copyright 2015 FUJITSU LIMITED  関数型言語とは  Javaと関数型言語  関数型言語の特徴 参照透過性 再帰 ストリーム 遅延評価  ストリームで注意すべきこと  Javaにおける並列プログラミングの実力 アジェンダ 50
  • 52. Stream APIによる並列性能 Copyright 2015 FUJITSU LIMITED レベル2のプログラム(fork/join使用)と レベル3のプログラム(stream使用)との比較 ベンチマークモデル 100万件の購買伝票を基に、 購入関連の高い商品群を抽出し、 未購入ユーザにレコメンドする。 指標 生産性(ソース行数)と性能(実行時間) 51
  • 53. 生産性(ソース行数) Copyright 2015 FUJITSU LIMITED static Map<Account, List<Product>> createProductMap(Account[] accounts) { return Arrays.stream(accounts).parallel() .collect(Collectors.toMap(Function.identity(), acc -> acc.records.stream() .flatMap(rec -> rec.orders.stream()) .map(ord -> ord.product) .distinct() .collect(Collectors.toList()))); } static Map<Account, List<Product>> createProductMap(Account[] accounts) { Map<Account, List<Product>> map = new ConcurrentHashMap<>(); ArrayList<ForkJoinTask> tlist = new ArrayList<>(); for (Account acc : accounts) { ForkJoinTask task = pool.submit(new Runnable() { public void run() { ArrayList<Product> list = new ArrayList<>(); for (PurchaseRecord pr : acc.records) for (Order ord : pr.orders) if (!list.contains(ord.product)) list.add(ord.product); map.put(acc, list); }}); tlist.add(task); } for (ForkJoinTask task : tlist) task.join(); return map; } レベル2のソース レベル3のソース 0 20 40 60 80 100 120 140 レベル2(fork/join) レベル3(stream) ス テ ッ プ 数 ソース行数(除共通部分) 52
  • 54. 性能(処理時間) Copyright 2015 FUJITSU LIMITED M10-4S SPARC64-X 4CPU x16core x2thread ・スレッド数が少ないほど、レベル2の方が良い ・スレッド数が大きくなると、差はほとんどなくなる傾向 0 5000 10000 15000 20000 25000 30000 35000 40000 2 4 8 16 32 64 128 時 間 ( m s ) スレッド数 レベル2(fork/join) レベル3(stream) 53
  • 55. まとめ 54 Copyright 2015 FUJITSU LIMITED オブジェクト指向言語 Javaによる高品質並列処理 関数型言語の仕組みを知る メニーコアを使い切る並列プログラミング ストリームプログラミング 参照透過・遅延評価の活用

Editor's Notes

  1. 0
  2. 1
  3. 11
  4. 17
  5. 26
  6. 29
  7. 33
  8. 42
  9. 50