SlideShare ist ein Scribd-Unternehmen logo
1 von 13
Downloaden Sie, um offline zu lesen
java, scalaをやってきてgoに思うこと
- golangで末尾再帰最適化は使えるか?-
2017/6/23 株式会社AJA 森 拓真
階乗
6! = 6 * 5 * 4 * 3 * 2 * 1 = 720
5! = 5 * 4 * 3 * 2 * 1 = 120
4! = 4 * 3 * 2 * 1 = 24
3! = 3 * 2 * 1 = 6
2! = 2 * 1 = 2
1! = 1 = 1
末尾再帰最適化
どんな風に書けばいいの?
末尾再帰 -> 関数の最後の呼び出しが自身の呼び出しになっていれば良い
再帰関数(スタックオーバーフローが起きる)
末尾再帰関数 (スタックオーバーフローが起きないように最適化可能)
再帰の場合
5!
コールスタック
4!
3!
2!
1!
return 1
return 2 * 1 = 1
return 3 * 2 = 6
return 4 * 6 = 24
func fact (5)
return 5 * 24 = 120
末尾再帰の場合
fact (4, 5)
コールスタック
fact(3, 20)
fact(2, 60)
fact(1, 120)
fact(0, 120)
return 120
return 120
return 120
return 120
func fact (5, 1)
return 120
n = 5 - 1 = 4
result = 5 * 1 = 5
n = 4 - 1 = 3
result = 5 * 4 = 20
n = 3 - 1 = 2
result = 20 *3 = 60
n = 2 - 1 = 1
result = 60 * 2 = 120
n = 1 - 1 = 0
result = 120
Scalaコンパイラの最適化って実際何してるの?
classファイルをjadで逆コンパイルした結果
階乗を求める末尾再帰な関数
末尾再帰最適化の対応状況
言語 対応状況 備考
java × 非対応
scala ◯ 対応 デフォルトで有効。
@tailrecアノテーションで、非末尾
再帰関数をコンパイルエラーにでき
る
ruby △ 対応 デフォルトでは無効。
tailcall_optimizationオプションを有効にすると利用
可能
javascript △ 対応 ES6からは、実装仕様として要求
Babelではトランスパイル時に最適化するようになっ
ている
Golangで末尾再帰最適化は使えるの?(1/5)
Golangで末尾再帰最適化は使えるの?(2/5)
特定の数までの足し上げる(ex: 5 + 4 + 3 + 2 + 1)末尾再帰関数
StackoverFlow
Golangで末尾再帰最適化は使えるの?(3/5)
BenchmarkRecursive-4 5000000 349 ns/op
BenchmarkRecursiveIteration-4 30000000 56.0 ns/op
BenchmarkTailRecursive-4 5000000 316 ns/op
パフォーマンス計測してみた
Golangで末尾再帰最適化は使えるの?(4/5)
go build -gcflags -S recursive.go &> assembly_code.txt
Golangで末尾再帰最適化は使えるの?(5/5)
● 使えない
まとめ
● golangでは末尾再帰は最適化されない。末尾再帰はfor, goto
を利用した記述方法に変更する。
● 今後も追加される気配は無い。

Weitere ähnliche Inhalte

Was ist angesagt?

PHPからgoへの移行で分かったこと
PHPからgoへの移行で分かったことPHPからgoへの移行で分かったこと
PHPからgoへの移行で分かったことgree_tech
 
何となく勉強した気分になれるパーサ入門
何となく勉強した気分になれるパーサ入門何となく勉強した気分になれるパーサ入門
何となく勉強した気分になれるパーサ入門masayoshi takahashi
 
バイナリアンを目指して For a binaryen
バイナリアンを目指して For a binaryenバイナリアンを目指して For a binaryen
バイナリアンを目指して For a binaryenEyes, JAPAN
 
本当は恐ろしい分散システムの話
本当は恐ろしい分散システムの話本当は恐ろしい分散システムの話
本当は恐ろしい分散システムの話Kumazaki Hiroki
 
SAT/SMTソルバの仕組み
SAT/SMTソルバの仕組みSAT/SMTソルバの仕組み
SAT/SMTソルバの仕組みMasahiro Sakai
 
DockerとPodmanの比較
DockerとPodmanの比較DockerとPodmanの比較
DockerとPodmanの比較Akihiro Suda
 
ラムダ計算入門
ラムダ計算入門ラムダ計算入門
ラムダ計算入門Eita Sugimoto
 
remote Docker over SSHが熱い
remote Docker over SSHが熱いremote Docker over SSHが熱い
remote Docker over SSHが熱いHiroyuki Ohnaka
 
Scala、DDD、Akkaで立ち向かう 〜広告配信システムに課せられた100msの制約〜
Scala、DDD、Akkaで立ち向かう 〜広告配信システムに課せられた100msの制約〜Scala、DDD、Akkaで立ち向かう 〜広告配信システムに課せられた100msの制約〜
Scala、DDD、Akkaで立ち向かう 〜広告配信システムに課せられた100msの制約〜MicroAd, Inc.(Engineer)
 
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」Takuto Wada
 
RustによるGPUプログラミング環境
RustによるGPUプログラミング環境RustによるGPUプログラミング環境
RustによるGPUプログラミング環境KiyotomoHiroyasu
 
テスト文字列に「うんこ」と入れるな
テスト文字列に「うんこ」と入れるなテスト文字列に「うんこ」と入れるな
テスト文字列に「うんこ」と入れるなKentaro Matsui
 
カスタムメモリマネージャと高速なメモリアロケータについて
カスタムメモリマネージャと高速なメモリアロケータについてカスタムメモリマネージャと高速なメモリアロケータについて
カスタムメモリマネージャと高速なメモリアロケータについてalwei
 
AVX2時代の正規表現マッチング 〜半群でぐんぐん!〜
AVX2時代の正規表現マッチング 〜半群でぐんぐん!〜AVX2時代の正規表現マッチング 〜半群でぐんぐん!〜
AVX2時代の正規表現マッチング 〜半群でぐんぐん!〜Ryoma Sin'ya
 
メタプログラミングって何だろう
メタプログラミングって何だろうメタプログラミングって何だろう
メタプログラミングって何だろうKota Mizushima
 
DockerコンテナでGitを使う
DockerコンテナでGitを使うDockerコンテナでGitを使う
DockerコンテナでGitを使うKazuhiro Suga
 

Was ist angesagt? (20)

PHPからgoへの移行で分かったこと
PHPからgoへの移行で分かったことPHPからgoへの移行で分かったこと
PHPからgoへの移行で分かったこと
 
何となく勉強した気分になれるパーサ入門
何となく勉強した気分になれるパーサ入門何となく勉強した気分になれるパーサ入門
何となく勉強した気分になれるパーサ入門
 
バイナリアンを目指して For a binaryen
バイナリアンを目指して For a binaryenバイナリアンを目指して For a binaryen
バイナリアンを目指して For a binaryen
 
明日使えないすごいビット演算
明日使えないすごいビット演算明日使えないすごいビット演算
明日使えないすごいビット演算
 
本当は恐ろしい分散システムの話
本当は恐ろしい分散システムの話本当は恐ろしい分散システムの話
本当は恐ろしい分散システムの話
 
SAT/SMTソルバの仕組み
SAT/SMTソルバの仕組みSAT/SMTソルバの仕組み
SAT/SMTソルバの仕組み
 
DockerとPodmanの比較
DockerとPodmanの比較DockerとPodmanの比較
DockerとPodmanの比較
 
ラムダ計算入門
ラムダ計算入門ラムダ計算入門
ラムダ計算入門
 
remote Docker over SSHが熱い
remote Docker over SSHが熱いremote Docker over SSHが熱い
remote Docker over SSHが熱い
 
Scala、DDD、Akkaで立ち向かう 〜広告配信システムに課せられた100msの制約〜
Scala、DDD、Akkaで立ち向かう 〜広告配信システムに課せられた100msの制約〜Scala、DDD、Akkaで立ち向かう 〜広告配信システムに課せられた100msの制約〜
Scala、DDD、Akkaで立ち向かう 〜広告配信システムに課せられた100msの制約〜
 
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
 
Java8でRDBMS作ったよ
Java8でRDBMS作ったよJava8でRDBMS作ったよ
Java8でRDBMS作ったよ
 
Plan 9のお話
Plan 9のお話Plan 9のお話
Plan 9のお話
 
RustによるGPUプログラミング環境
RustによるGPUプログラミング環境RustによるGPUプログラミング環境
RustによるGPUプログラミング環境
 
テスト文字列に「うんこ」と入れるな
テスト文字列に「うんこ」と入れるなテスト文字列に「うんこ」と入れるな
テスト文字列に「うんこ」と入れるな
 
カスタムメモリマネージャと高速なメモリアロケータについて
カスタムメモリマネージャと高速なメモリアロケータについてカスタムメモリマネージャと高速なメモリアロケータについて
カスタムメモリマネージャと高速なメモリアロケータについて
 
AVX2時代の正規表現マッチング 〜半群でぐんぐん!〜
AVX2時代の正規表現マッチング 〜半群でぐんぐん!〜AVX2時代の正規表現マッチング 〜半群でぐんぐん!〜
AVX2時代の正規表現マッチング 〜半群でぐんぐん!〜
 
メタプログラミングって何だろう
メタプログラミングって何だろうメタプログラミングって何だろう
メタプログラミングって何だろう
 
DockerコンテナでGitを使う
DockerコンテナでGitを使うDockerコンテナでGitを使う
DockerコンテナでGitを使う
 
プログラムを高速化する話
プログラムを高速化する話プログラムを高速化する話
プログラムを高速化する話
 

goで末尾再帰最適化は使えるか?