4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

日本語プログラミング言語「なでしこ」Advent Calendar 2023

Day 16

なでしこ3はPythonより6.5倍速い!ベンチマークしてみました

Last updated at Posted at 2023-12-15

なでしこの実行速度が話題になっていたので、久々に、手元にあるMacbook Pro(m1)でベンチマークしてみました。なでしこ3のPC版(Node.js版)と各種スクリプト言語を比較してみましょう。

再帰処理フィボナッチ勝負

まずはフィボナッチで試してみましょう。

なでしこ3

なでしこ3.4.24で試してみました。

fib.nako3
●FIB(Nの)
  もし、N<2ならばNで戻る。
  ((N-1)のFIB)+((N-2)のFIB)で戻る。
ここまで。
(40のFIB)を表示。

実行してみると、下記のように4秒かかりました。

time cnako3 fib.nako3
102334155
cnako3 fib.nako3  3.94s user 0.05s system 98% cpu 4.078 total

Python3

次に、Python 3.9.7で試してみます。速度には影響しないものの、タイプヒントも付けてみました。

fib.py
def fib(n:int) -> int:
    if n < 2: return n
    return fib(n - 2) + fib(n - 1)
 
print(fib(40))

実行してみましょう。すると、なんと26.4秒かかってしまいました。Python遅いと言われていますが、やはりPython3.9だと再帰のコードが遅いですね。

time python3 fib.py
102334155
python3 fib.py  26.16s user 0.03s system 99% cpu 26.392 total

Perl

次に、Perlで試してみましょう。

fib.pl
sub fib($) {
    return $_[0] if ($_[0] < 2);
    return fib($_[0] - 2) + fib($_[0] - 1);
}
 
print fib(40), "\n";

実行してみましょう。36.7秒かかり、Python3以上に遅いことが分かります。

time perl fib.pl
102334155
perl fib.pl  36.48s user 0.02s system 99% cpu 36.719 total

Node.js

次に、なでしこ3のエンジンであるNode.jsで試してみましょう。

fib.js
function fib(n) {
    if (n < 2) return n;
    return fib(n - 2) + fib(n - 1);
}
console.log(fib(40));

実行してみましょう。早い!やはり早いです!

time node fib.js
102334155
node fib.js  1.28s user 0.01s system 98% cpu 1.316 total

ここから、なでしこを使うと、コンパイル処理とか、内部で変数チェックとか、余分な処理が走るため、JSの3倍遅くなる事も分かります。

PHP8

次に、PHP8.3.0で試してみましょう。PHP8になり、ずいぶん処理が速くなったと聞いていましたが、どうでしょうか。

fib.php
<?php
function fib($n) {
    if ($n < 2) return $n;
    return fib($n - 2) + fib($n - 1);
}
 
echo fib(40)."\n";

実行してみましょう。9.695秒で、やはり、Node.jsには追いついていません。

time php fib.php
102334155
php fib.php  9.60s user 0.02s system 99% cpu 9.695 total

Ruby

次に、日本発のプログラミング言語のRuby2.6.10p210で試してみましょう。Ruby3でなくてすみません。

fib.rb
def fib(n)
    return n if (n < 2)
    return fib(n - 2) + fib(n - 1)
end
 puts fib(40)

実行してみましょう。13秒です!良い感じです。

time ruby fib.rb
102334155
ruby fib.rb  12.92s user 0.05s system 99% cpu 13.078 total

結果発表

結果をまとめてみました。今回の、スクリプト言語速度対決は、Node.jsが一番速く、実行エンジンとしてNode.jsを使っているなでしこ3がそれに次いで速いという結果になりました。とは言え、どの言語も素晴らしく、速度が遅い部類のPythonが2023年、最も使われています。もはや、PCは十分速くなり、素の実行速度など、それほど気にする必要は無いという時代になっていますね。

順位 言語 処理時間
1 Node.js 1.316
2 なでしこ3 4.078
3 PHP8 9.695
4 Ruby2.6 13.078
5 Python3 26.392
6 Perl5 36.719

(オマケ) 素数計算で対決

次に、オマケで、12345678以下の素数の個数を調べるプログラムで比較してみましょう。

soe.nako3
●(最大値の)素数取得とは:
  素数リスト=[]
  A=真を(最大値+1)だけ配列要素作成。
  Iを2から最大値まで繰り返す:
    もし、A[I]が真ならば:
      素数リストにIを配列追加。
      Jを(I*I)から最大値までIずつ増やし繰り返す:
        A[J] = 偽
  それは素数リスト
12345678の素数取得して要素数を表示。

実行してみましょう。0.785秒です。

time cnako3 soe.nako3
809227
cnako3 soe.nako3  0.73s user 0.08s system 103% cpu 0.785 total

次にPython3です。

soe.py
def sieve_of_eratosthenes(limit):
    primes = []
    a = [True] * (limit + 1)
    for i in range(2, limit + 1):
        if a[i]:
            primes.append(i)
            for j in range(i*i, limit + 1, i):
                a[j] = False
    return primes

print(len(sieve_of_eratosthenes(12345678))) 

実行してみましょう。1.849秒でした。なでしこよりも2.4倍遅いという結果になりました。

time python3 soe.py
809227
python3 soe.py  1.73s user 0.04s system 96% cpu 1.849 total

続いて、PHPで試してみましょう。

soe.php
<?php
function sieve_of_eratosthenes($limit) {
    $primes = array();
    $a = array_fill(0, $limit + 1, true);
    for ($i = 2; $i <= $limit; $i++) {
        if ($a[$i]) {
            array_push($primes, $i);
            for ($j = $i * $i; $j <= $limit; $j += $i) {
                $a[$j] = false;
            }
        }
    }
    return $primes;
}
$primes = sieve_of_eratosthenes(12345678);
echo count($primes)."\n";

PHPで試してみると、メモリエラーで実行できないようになっていました。コマンドラインで-d memory_limit=-1にすると、このエラーを回避できるとのこと、学びになりました。実行時間は、1.775秒でした。

time php -d memory_limit=-1 soe.php
809227
php -d memory_limit=-1 soe.php  1.69s user 0.05s system 98% cpu 1.775 total

素数計算勝負の結果

次のようになりました。今回は、3言語のみの比較ですが、やはり、Python3が遅いという結果です。

| 順位 | 言語 | 処理時間 |
| 1 | なでしこ3 | 0.785 |
| 2 | PHP8 | 1.775 |
| 3 | Python3 | 1.849 |

まとめ

楽しいスクリプト言語ごとの速度結果勝負ですが、どうだったでしょうか。

スクリプト言語では、ChromeのJS実行エンジンを利用しているNode.jsがダントツで速く、虎の威を借る狐である「なでしこ3」は、それに次いで速いという結果になりました。Node.jsと比べると何倍も遅くなっていますが、PHPやPythonよりも速いので十分満足です。

もちろん、言語ごとに、最適化オプションがあるので、もっと速く実行することもできるでしょう。なでしこ3も、素のJavaScriptを出力するモードがあるので、これを利用すると、もっと速く実行できます。また、変数の引数チェックを省略するモードもあるので、それを使うともっと速くなります。

それでも、一番使い勝手の良いデフォルトモードで比較するのが公平なので、できるだけデフォルト状態で試してみました。

皆様の参考になれば幸いです。

4
1
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?