2022-09-09æ¹è¨ï¼ gcc ãã¼ã¸ã§ã³ãå¤ãããã®ã¨ãC ãå
é¨è¨æ¸¬ã§ãªãã£ãç¹ãæ¹ãè¨æ¸¬ããªããã¾ãããçµæãRust 㯠C ããéãã¯ãªããªãã¾ãããç´ãããããã¨ã§ãããããªãããã¾ããgcc ã®ãã¼ã¸ã§ã³ã¢ããã«ä¼´ããPython ããã³ Ruby ã«ã¤ãã¦ã¯ãã«ãã¨è¨æ¸¬ãããªãããã®ã§ãããããå°ãéãå¤ã«å¤ãã£ã¦ãã¾ãããã®ç¹ãã©ãããããããã
2022-09-10追è¨ï¼ãè¦æã®ãã£ã Python numba.njit ä½¿ç¨æã¨ Go ã®çµæã追å ãã¾ãããPHP 㯠JIT æå¹åãé¢åã ã£ãã®ã§æå¿µãã¾ãã^^;
2022-09-10追è¨2ï¼C ã®è¨æ¸¬ã§ clock() ã使ãã®ã¯ãã§ã¢ã§ã¯ãªãã¨ããææãããã¾ããã®ã§ã念ã®ãã clock_gettime() ã使ç¨ããã³ã¼ãã«å·®ãæ¿ãã¾ãããçµæã«å¤§ããªå·®ã¯ããã¾ããã
2022-09-10追è¨3ï¼PHP ã® JIT ã 有効化されない理由と回避方法 ãåãã£ãã®ã§ãè¨æ¸¬ãã¦è¿½å ãã¾ããã
2022-09-11追è¨ï¼PyPy ã®çµæã追å ãã¾ããã
2022-09-12追è¨ï¼Common Lisp ã®çµæã追å ãã¾ããã
2022-09-13追è¨ï¼Javaï¼HotSpotãGraalVMï¼ã¨ C# ãGraalVM ãã¤ã³ã¹ãã¼ã«ããã¤ãã§ã« TruffleSqueakãGraalPythonãTruffleRuby ã®çµæã追å ãã¾ãããJava HotSpotVM ã C ããéããªã£ã¦ãã¾ã£ãã®ããã¾ã§ãã^^;ãâ»ãã®å¾ã使ç¨ã§ããã³ã¢æ°ã1ã«éã£ããã弿°ãã³ãã³ãã©ã¤ã³ããä¸ãããn=8 ã§ãæ¯è¼ããçã®æ¤è¨¼ããã¾ãããåç¾ãããã§ã¢ãã«æ¬ ããç¹ã¯ç¹ã«è¦ã¤ãããã¾ããã§ããã
2022-09-13追è¨2ï¼PHP.ini ã®è¨å®ããããã£ã¦ãã(opcache.jit_buffer_size=128MBã¨æå¾ã«ä½è¨ãª"B"ãä»ãã¦ãã¾ã£ã¦ãã^^;)ããã§ JIT ãå¹ãã¦ãã¾ããã§ãããããããªãããご指摘ããã¿ããã¾ããã¨ãããã¨ã§ãPHP ã¯ãJITãããã®çµæãæ¹ãã¦è¿½å ãã¾ããã
2022-09-13追è¨3ï¼Ruby MJIT ã®çµæã追å ãã¾ããã
2022-09-16追è¨ï¼ã詳ããæ¹ããご指摘ãããã ã Common Lisp ã®æé©åæã®çµæãæ´æ°ãã¾ãããæå
ã®ç°å¢ã§ã¯ C ããéããJava ã軽ãå¶ãã¦ä»ã®ã¨ããæéã§ããLisp æã (ããããªæå³ã§^^;)ã
2022-09-17追è¨ï¼C# æé©åå¾ã¨ Swift ã®çµæã追å ãã¾ããã
2022-12-29追è¨ï¼F# ã®çµæã追å ãã¾ããã
竹å 颿° (今回はyを返す正式版) tarai(14, 7, 0) ã«ãããæéããæå ã®ç°å¢ï¼Intel Core i9-9880H @ 2.30GHzãWin10 64-bit WSLç°å¢ï¼ã§è¨æ¸¬ãã¦ã¿ã¾ããã
- またまた久しぶりに竹内関数で JavaScript、Python、Ruby、Scheme と Smalltalk とを戦わせてみる
- 久しぶりに竹内関数で JavaScript、Python、Ruby、Scheme と Smalltalk とを戦わせてみる
Smalltalk 㯠Squeak 㨠Pharo ã® Winçã使ãã¾ãããä»åããã£ããã¯å¾æ¥éããããã¯(ç¡å颿°)çã®å®è£ ã§è¨æ¸¬ããã®ã§ãããã¿ã¤ãã«ã®éããYJITããã®Rubyã«æãã®ã»ãèèããããã¯ãä½è£ããªããªã£ãã®ã§ãå°ãã§ãå·®ãä»ããããããã«ã¡ã½ããçã§ã試ãã¾ãããð
Cã®çµæããã¾ãã¾1ç§ã¡ããã©ã ã£ãã®ã§ãä»åã¯çµæã®æ°å¤ããã®ã¾ã¾ãCã®ä½åããã«ãªãã¾ããRuby YJIT ããã«ãããã¤ãã§ã« Rust ãã¤ã³ã¹ãã¼ã«ããã®ã§ Rust ã§ãè¨æ¸¬ãã¦ã¿ã¾ããï¼ã³ã¼ã㯠Rustでたらいまわし ãããåããã¦æ¹å¤ãã¾ããï¼ããCããéããã¤ãªãã(?)ã§ Julia ã§ã試ãã¦ã¿ã¾ããããã©ããã竹å
颿°ã§ã¯ããã¾ã§éãã¯ãªããªãã¿ããã§ãï¼ã§ãååéãï¼ï¼ã
| ãè¨èªã | ãå¦çç³»ã | ã çµæã | ã 対Cæ¯ã | åå(ãã»ç«¹å 颿°)ã®å¯¾Cæ¯ |
| ãCã | ãgcc 9.4.0ã | ã0.735 secã | ã1.00åã | ãâã |
| ãSmalltalk (ã¡ã½ãã)ã | ãSqueak 6.0ã | ã2.55 secã | ã3.47åã | ãâã |
| ãã | ãTruffleSqueak 22.2.0ã | ã5.59 secã | ã7.61åã | ãâã |
| ãã | ãPharo 10.0.0ã | ã2.45 secã | ã3.33åã | ãâã |
| ãSmalltalk (ãããã¯)ã | ãSqueak 6.0ã | ã3.87 secã | ã5.27åã | ã4.45å (Squeak 5.3)ã |
| ãã | ãTruffleSqueak 22.2.0ã | ã21.1 secã | ã28.7åã | ãâã |
| ãã | ãPharo 10.0.0ã | ã3.62 secã | ã4.93åã | ã4.81å (Pharo 8.0.0)ã |
| ãPythonã | ãPython 3.11.0rc1ã | ã29.3 secã | ã39.9åã | ãâã |
| ãã | ãPython 3.10.7ã | ã53.0 secã | ã72.1åã | ã74.6å (3.10.0b3+)ã |
| ãã | ãPython 3.10.7 (numba.njitä½¿ç¨æ)ã | ã3.58 secã | ã4,87åã | ãâã |
| ãã | ãPyPy 3.9-7.3.9ã | ã9.19 secã | ã12.5åã | ãâã |
| ãã | ãGraalPython 3.8.5ã | ã7.20 secã | ã9.80åã | ãâã |
| ãRubyã | ãRuby 3.2.0dev (YJIT)ã | ã4.08 secã | ã5.55åã | ãâã |
| ãã | ãRuby 3.2.0dev (MJIT)ã | ã5.47 secã | ã7.44åã | ãâã |
| ãã | ãRuby 3.2.0dev (JITãªã)ã | ã17.7 secã | ã24.1åã | ã22.2å (3.1.0dev)ã |
| ãã | ãtruffleruby 22.2.0ã | ã5.14 secã | ã6.99åã | ãâã |
| ãJavaScriptã | ãNode.js 17.9.1ã | ã2.14 secã | ã2.91åã | ã2.84å (17.9.1)ã |
| ãJuliaã | ãJulia 1.8.0ã | ã1.18 secã | ã1.61åã | ãâã |
| ãRustã | ãrustc 1.63.0ã | ã0.790 secã | ã1.07åã | ãâã |
| ãGoã | ãgo1.19ã | ã0.849 sec | ã1.16åã | ãâã |
| ãPHPã | ãPHP 8.1.0 (JITãã)ã | ã4.47 sec | ã6.08åã | ãâã |
| ãã | ãPHP 8.1.0 (JITãªã)ã | ã11.3 sec | ã15.4åã | ãâã |
| ãCommon Lispã | ãSBCL 1.4.5ã | ã2.61 secã | ã3.55åã | ãâã |
| ãã | ãSBCL 1.4.5 (æé©åãã)ã | ã0.590 secã | ã0.803åã | ãâã |
| ãJavaã | ãOpenJDK 18.0.2.1ã | ã0.655 sec | ã0.891åã | ãâã |
| ãã | ãOpenJDK 17.0.4 GraalVM CE 22.2.0ã | ã0.884 sec | ã1.20åã | ãâã |
| ãC#ã | ã.Net 6.0.400ã | ã1.81 sec | ã2.46åã | ãâã |
| ãã | ã.Net 6.0.400 (æé©åãã)ã | ã1.05 sec | ã1.43åã | ãâã |
| ãF#ã | ã.Net 6.0.400ã | ã1.27 sec | ã1.73åã | ãâã |
| ãã | ã.Net 6.0.400 (æé©åãã)ã | ã0.983 sec | ã1.34åã | ãâã |
| ãSwiftã | ãswiftc 5.7ã | ã5.58 sec | ã7.59åã | ãâã |
| ãã | ãswiftc 5.7 (æé©åãã)ã | ã0.780 sec | ã1.06åã | ãâã |
x ã y ãã大ãããªãã¨ãã« z ã§ã¯ãªã y ãè¿ãããã«å¤ããã®ã¨ã竹å å çã®ã³ã¼ãã«å£ã£ã¦ if å ã®é çªãå¤ãã以å¤ã¯ååã¨ã»ã¼ä¸ç·ã§ãããã»ï¼â¦ã¨é£å¼ããã¨èªå¼ãããã¾ãããããã«ã¼ã·ã¼çãï¼ã¨éã£ã¦æ£å¼ãªç«¹å 颿° tarai(2n, n, 0) ã§ã¯ n=10 ã ã¨ç¡çã£ã½ããã ã£ãã®ã§ãn=7 ã§è¨ç®ããã¾ããã
Pythonã¯ä¼¸ã³ããããã£ã±ãããã®ã§ã4å¹´å¾ã«5åã®é度ãã¯å¤§ä¸å¤«ããã§ããï¼
Smalltalk (ã¡ã½ããç)
ãTarai class >>ãã¯ã¯ã©ã¹ãã©ã¦ã¶ãªã©ã使ã£ã¦å®ç¾©ãããTaraiãã¯ã©ã¹ã®ã¯ã©ã¹ã¡ã½ããã« x:y:z: ã¡ã½ãããå®ç¾©ãããã¨ãæå³ãã¾ãã
Tarai class >> x: x y: y z: z ^ x > y ifTrue: [ Tarai x: (Tarai x: x-1 y: y z: z) y: (Tarai x: y-1 y: z z: x) z: (Tarai x: z-1 y: x z: y)] ifFalse: [y]
| ans | (Time millisecondsToRun: [ans := Tarai x: 14 y: 7 z: 0]) -> ans
Smalltalk (ãããã¯ç)
| tarai ans | tarai := nil. tarai := [:x :y :z | x > y ifTrue: [ tarai value: (tarai value: x-1 value: y value: z) value: (tarai value: y-1 value: z value: x) value: (tarai value: z-1 value: x value: y)] ifFalse: [y] ]. (Time millisecondsToRun: [ans := tarai value: 14 value: 7 value: 0]) -> ans
Cã®çµæã¨ä½¿ç¨ããã³ã¼ã
$ gcc --version
gcc (Ubuntu 9.4.0-1ubuntu1~18.04) 9.4.0
...
$ gcc -O3 tarai.c -o tarai_O3
$ ./tarai_O3
0.734794 14
$ cat tarai.c
#include <stdio.h>
#include <time.h>
int tarai(int x, int y, int z){
if (x > y){
return tarai( tarai(x-1, y, z), tarai(y-1, z, x), tarai(z-1, x, y) );
} else {
return y;
}
}
int main(void){
struct timespec time1, time2;
float delta;
clock_gettime(CLOCK_REALTIME, &time1);
int ans = tarai(14, 7, 0);
clock_gettime(CLOCK_REALTIME, &time2);
delta = time2.tv_sec - time1.tv_sec + (float)(time2.tv_nsec - time1.tv_nsec) / 1000000000;
printf("%f %d\n", delta, ans);
return 0;
}
Pythonã®çµæã¨ä½¿ç¨ããã³ã¼ã
$ python -V; python tarai.py
Python 3.10.7
53.01142239570618 14
$ python -V; python tarai.pyPython 3.11.0rc1
29.337019681930542 14
$ cat tarai.py
from time import time
def tarai(x, y, z):
if x > y:
return tarai( tarai(x-1, y, z), tarai(y-1, z, x), tarai(z-1, x, y) )
else:
return y
start = time()
ans = tarai(14, 7, 0)
print( time() - start, ans )
Python numba.njit ä½¿ç¨æã®çµæã¨ã³ã¼ã
$ pip list
Package Version
---------- -------
llvmlite 0.39.1
numba 0.56.2
numpy 1.23.2
pip 22.2.2
setuptools 59.8.0
$ python -V; python tarai-njit.py
Python 3.10.7
3.5813117027282715 14
$ cat tarai-njit.py
from time import time
from numba import njit, i2
@njit(i2(i2,i2,i2))
def tarai(x, y, z):
if x > y:
return tarai( tarai(x-1, y, z), tarai(y-1, z, x), tarai(z-1, x, y) )
else:
return y
start = time()
ans = tarai(14, 7, 0)
print( time() - start, ans )
PyPyã®ãã¼ã¸ã§ã³ã¨çµæ
$ pypy -V; pypy tarai.py Python 3.9.12 (05fbe3aa5b0845e6c37239768aa455451aa5faba, Mar 29 2022, 08:15:34) [PyPy 7.3.9 with GCC 10.2.1 20210130 (Red Hat 10.2.1-11)] 9.192949771881104 14
GraalPython ã®ãã¼ã¸ã§ã³ã¨çµæ
$ graalpython -V; graalpython tarai.py GraalVM Python 3.8.5 (GraalVM CE Native 22.2.0) 7.203999996185303 14
Rubyã®çµæã¨ä½¿ç¨ããã³ã¼ã
$ ruby -v tarai.rb
ruby 3.2.0dev (2022-09-08T15:46:21Z master 6d93644ba1) [x86_64-linux]
14
17.7318423
$ ruby --yjit -v tarai.rb
ruby 3.2.0dev (2022-09-08T15:46:21Z master 6d93644ba1) +YJIT [x86_64-linux]
14
4.084934
$ ruby -v --mjit tarai7.rb
ruby 3.2.0dev (2022-09-08T15:46:21Z master 6d93644ba1) +MJIT [x86_64-linux]
14
5.468897
$ cat tarai.rb
def tak(x, y, z)
if x > y then
tak(tak(x-1, y, z), tak(y-1, z, x), tak(z-1, x, y))
else
y
end
end
start = Time.now
puts tak(14, 7, 0)
puts Time.now - start
TruffleRuby ã®ãã¼ã¸ã§ã³ã¨çµæ
$ ruby -v tarai.rb truffleruby 22.2.0, like ruby 3.0.3, GraalVM CE Native [x86_64-linux] 14 5.1394269999999995
JavaScript (Node.js) ã®çµæã¨ä½¿ç¨ããã³ã¼ã
$ node -v; node tarai.js
v17.9.1
2136 14
$ cat tarai.js
function tarai(x, y, z) {
if(x > y) {
return tarai( tarai(x-1, y, z), tarai(y-1, z, x), tarai(z-1, x, y) );
} else {
return y;
}
}
var start = (new Date()).getTime();
var ans = tarai(14, 7, 0);
console.log((new Date()).getTime() - start, ans)
Juliaã®çµæã¨ä½¿ç¨ããã³ã¼ã
$ julia -v; julia tarai.jl julia version 1.8.0 1.184309 seconds 14 $ cat tarai.jl tak(x, y, z) = x > y ? tak(tak(x - 1, y, z), tak(y - 1, z, x), tak(z - 1, x, y)) : y @time ans = tak(14, 7, 0) println(ans)
Rustã®çµæã¨ä½¿ç¨ããã³ã¼ã
$ rustc -V
rustc 1.63.0 (4b91a6ea7 2022-08-08)
$ rustc -C opt-level=3 -C debug_assertions=no tarai.rs
$ ./tarai
14
0.7899205
$ cat tarai.rs
use std::time::Instant;
fn tarai(x: i32, y: i32, z: i32) -> i32 {
if x > y {
tarai(tarai(x - 1, y, z), tarai(y - 1, z, x), tarai(z - 1, x, y))
} else {
y
}
}
fn main() {
let start_tarai = Instant::now();
println!("{}", tarai(14, 7, 0));
let end_tarai = start_tarai.elapsed();
let tarai_sec = end_tarai.as_secs() as f64 +
end_tarai.subsec_nanos() as f64 / 1000_000_000.0;
println!("{}", tarai_sec);
}
Goã®çµæã¨ä½¿ç¨ããã³ã¼ã
$ go version
go version go1.19 linux/amd64
$ go run tarai.go
849 14
$ cat tarai.go
package main
import (
"fmt"
"time"
)
func tarai(x int, y int, z int) int {
if x > y {
return tarai(tarai(x - 1, y, z),
tarai(y - 1, z, x),
tarai(z - 1, x, y))
} else {
return y
}
}
func main() {
start := time.Now()
ans := tarai(14, 7, 0)
fmt.Printf("%v %v\n", time.Since(start).Milliseconds(), ans)
}
PHPã®çµæã¨ä½¿ç¨ããã³ã¼ã
$ php -i | grep opcache
opcache.enable => On => On
opcache.enable_cli => On => On
opcache.jit => tracing => tracing
opcache.jit_buffer_size => 128M => 128M
opcache.revalidate_freq => 60 => 60
...
$ php -v; php tarai.php
PHP 8.1.9 (cli) (built: Sep 10 2022 22:10:58) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.1.9, Copyright (c) Zend Technologies
with Zend OPcache v8.1.9, Copyright (c), by Zend Technologies
4.473552942276 14
$ php -i | grep opcache
opcache.jit_buffer_size => 0 => 0
...
$ php tarai.php
11.325684070587 14
$ cat tarai.php
<?php
function tarai(int $x, int $y, int $z) : int {
if ($x > $y) {
return tarai(tarai($x - 1, $y, $z),
tarai($y - 1, $z, $x),
tarai($z - 1, $x, $y));
} else {
return $y;
}
}
$start = microtime(true);
$ans = tarai(14, 7, 0);
$time = microtime(true) - $start;
echo "{$time} {$ans}\n";
Common Lisp (æé©åãªã)ã®çµæã¨ä½¿ç¨ããã³ã¼ã
$ sbcl --version; sbcl --script tarai.lisp
SBCL 1.4.5.debian
Evaluation took:
2.608 seconds of real time
2.607781 seconds of total run time (2.606888 user, 0.000893 system)
100.00% CPU
6,008,334,038 processor cycles
0 bytes consed
14
$ cat tarai.lisp
(defun tarai (x y z)
(if (> x y)
(tarai (tarai (1- x) y z) (tarai (1- y) z x) (tarai (1- z) x y))
y
)
)
(defvar *ans*)
(time (setq *ans* (tarai 14 7 0)))
(princ *ans*)
(terpri)
Common Lisp (æé©åãã)ã®çµæã¨ä½¿ç¨ãããhttps://g000001.cddddr.org/3872263095ãã§ãæç¤ºããã ããã³ã¼ã
$ sbcl --script tarai7-g1.lisp
Evaluation took:
0.590 seconds of real time
0.590533 seconds of total run time (0.590533 user, 0.000000 system)
100.17% CPU
1,360,580,830 processor cycles
0 bytes consed
14
$ cat tarai-g1.lisp
(defun tarai (x y z)
(declare (optimize (speed 3) (debug 0) (safety 0)))
(labels ((tarai (x y z)
(declare (fixnum x y z))
(the fixnum
(if (> x y)
(tarai (tarai (1- x) y z)
(tarai (1- y) z x)
(tarai (1- z) x y))
y))))
(declare (inline tarai))
(tarai x y z)))
(compile 'tarai)
(princ (time (tarai 14 7 0)))
(terpri)
Java HotSpotVMã®çµæã¨ä½¿ç¨ããã³ã¼ã
$ java -version; javac -version
openjdk version "18.0.2.1" 2022-08-18
OpenJDK Runtime Environment (build 18.0.2.1+1-1)
OpenJDK 64-Bit Server VM (build 18.0.2.1+1-1, mixed mode, sharing)
javac 18.0.2.1
$ javac tarai.java
$ java Tarai
655
14
$ cat tarai.java
class Tarai {
static private int tarai(int x, int y, int z) {
if (x > y) {
return tarai(tarai(x - 1, y, z), tarai(y - 1, z, x), tarai(z - 1, x, y));
} else {
return y;
}
}
static public void main(String args[]) {
long start = System.currentTimeMillis();
int ans = tarai(14, 7, 0);
System.out.println(System.currentTimeMillis() - start);
System.out.println(ans);
}
}
Java GraalVMã®ãã¼ã¸ã§ã³ã¨çµæ
$ java -version; javac -version openjdk version "17.0.4" 2022-07-19 OpenJDK Runtime Environment GraalVM CE 22.2.0 (build 17.0.4+8-jvmci-22.2-b06) OpenJDK 64-Bit Server VM GraalVM CE 22.2.0 (build 17.0.4+8-jvmci-22.2-b06, mixed mode, sharing) javac 17.0.4 $ javac tarai.java $ java Tarai 884 14
C#ã®çµæã¨ä½¿ç¨ããã³ã¼ã
$ dotnet --version
6.0.400
$ dotnet new console -o Tarai_cs
$ cat Program.cs
using System.Diagnostics;
class Program
{
static void Main()
{
var sw = new Stopwatch();
sw.Start();
var ans = Tarai(14, 7, 0);
sw.Stop();
Console.WriteLine("" + sw.ElapsedMilliseconds + " " + ans);
}
static int Tarai(int x, int y, int z)
{
if (x > y) {
return Tarai( Tarai(x - 1, y, z),
Tarai(y - 1, z, x),
Tarai(z - 1, x, y));
} else {
return y;
}
}
}
$ dotnet run
1809 14
$ dotnet run --configuration Release
1048 14
F#ã®çµæã¨ä½¿ç¨ããã³ã¼ã
$ dotnet --version
6.0.400
$ dotnet new console -lang F# -o Tarai_fs
$ cat Program.fs
let rec tarai x y z =
if x > y then
tarai (tarai (x - 1) y z) (tarai (y - 1) z x) (tarai (z - 1) x y)
else
y
let stopWatch = System.Diagnostics.Stopwatch.StartNew()
let ans = tarai 14 7 0
stopWatch.Stop()
printfn "%f %d" stopWatch.Elapsed.TotalMilliseconds ans
$ dotnet run
1272.238400 14
$ dotnet run --configuration Release
983.585300 14
Swiftã®çµæã¨ä½¿ç¨ããã³ã¼ã
$ swift -version
Swift version 5.7 (swift-5.7-RELEASE)
Target: x86_64-unknown-linux-gnu
$ swiftc tarai.swift && ./tarai
14 5.5811779499053955
$ swiftc -Ounchecked tarai.swift && ./tarai
14 0.7802159786224365
$ cat tarai.swift
import Foundation
import CoreFoundation
func tarai(_ x: Int, _ y: Int, _ z: Int) -> Int {
if x > y {
return tarai(tarai(x - 1, y, z),
tarai(y - 1, z, x),
tarai(z - 1, x, y))
} else {
return y
}
}
let start = CFAbsoluteTimeGetCurrent()
let ans = tarai(14, 7, 0)
print("\(ans) \(CFAbsoluteTimeGetCurrent() - start)")