TotallyLazyとJCompiloについて
TotallyLazyは、javaで関数型プログラミングをしやすくするためのライブラリ。
JCompiloは、末尾再帰削除を実施するコンパイラ。
利用した結果
今回、TotallyLazyの@tailrecでアノテートしたメソッドをJCompilo java compilerにてコンパイルし、
末尾再帰除去を行ったバイトコードが作成されるのを確認した。
確認環境
環境は、
- Intellij IDEA12.1.6
- TotallyLazy 1166
https://code.google.com/p/totallylazy/ - JCompilo (Java Compiler) 160 (Intellij IDEA plugin)
http://plugins.jetbrains.com/plugin/7122
Intellij IDEAで、JCompiloを使う設定は上記リンクを参照 - ASM Bytecode Outline (IntleliJ IDEA plugin)
http://plugins.jetbrains.com/plugin/5918
コンパイル後、ツールバーのCodeまたは右メニューからShow Bytecode Outlineを選択
なお、1.8には未対応の模様
なお、TotallyLazyとJCompiloの組み合わせには、独自のラムダ式構文もあったが、
Java8でラムダ式合わせて、独自のラムダ構文は削除された模様。
コード類
利用したコード
import com.googlecode.totallylazy.annotations.tailrec;
public class gcdUtil {
@tailrec //totalylazyのtailrecアノテーション
public static int gcd_tco(int x, int y) {
if (y == 0) return x;
return gcd_tco(y, x % y);
}
public static int gcd(int x, int y) {
if (y == 0) return x;
return gcd(y, x % y);
}
}
asmで、classファイルをgroovified(バイトコードを読みやすくgroovy化)した結果
// class version 50.0 (50)
// access flags 0x21
public class gcdUtil {
@groovyx.ast.bytecode.Bytecode
public void <init>() {
aload 0
invokespecial 'java/lang/Object.<init>','()V'
return
}
@groovyx.ast.bytecode.Bytecode
public static int gcd_tco(int a,int b) {
l0
iload 1
ifne l1
iload 0
ireturn
l1
iload 1
iload 0
iload 1
irem
istore 1
istore 0
_goto l0 //末尾最適化された!
}
@groovyx.ast.bytecode.Bytecode
public static int gcd(int a,int b) {
iload 1
ifne l0
iload 0
ireturn
l0
iload 1
iload 0
iload 1
irem
invokestatic 'gcd.gcd','(II)I' //末尾関数呼び出し
ireturn
}
}
mavenのpomファイル
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>gcd</groupId>
<artifactId>gcd</artifactId>
<version>1.0-SNAPSHOT</version>
<repositories>
<repository>
<id>bodar.com</id>
<name>bodar.com</name>
<url>http://repo.bodar.com/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>com.googlecode.totallylazy</groupId>
<artifactId>totallylazy</artifactId>
<version>1166</version>
</dependency>
</dependencies>
</project>
参考記事
Why Functional Programming in Java is NOT Dangerous | Yesterday I was wrong
http://dan.bodar.com/2013/01/23/why-functional-programming-in-java-is-not-dangerous/
その他(JVMの末尾再帰最適化について)
IBM JavaではJVMのJITコンパイラが末尾再帰最適化を行っている。
Javaコードの診断: Javaコードのパフォーマンスを向上させる
末尾再帰変換はアプリケーションの速度を向上させる可能性はあるが、すべてのJVMで可能な操作ではない
http://www.ibm.com/developerworks/jp/java/library/j-diag8/
Linux 上の IBM User Guide for Java V7 > IBM Software Developers Kit (SDK) for Java について > JIT コンパイラー > JIT コンパイラーによるコードの最適化方法
フェーズ 2 - ローカル最適化
http://pic.dhe.ibm.com/infocenter/java7sdk/v7r0/index.jsp?topic=%2Fcom.ibm.java.lnx.70.doc%2Fdiag%2Funderstanding%2Fjit_optimize.html
ダウンロード
http://www.ibm.com/developerworks/java/jdk/
http://www.ibm.com/developerworks/java/jdk/linux/download.html
上記の記事に沿って、IBM SDK, Java Technology Edition, Version 7 Release 1 (linux 32-bit x86)でも対応しているのを確認した。