V言語の実行速度をベンチマーク


巷で噂のV言語。シンプル・高速・安全を謳っており、特に高速コンパイルが特徴のようで、ベンチマークも載っています。
一方実行速度については、公式によると

パフォーマンス

  • As fast as C

とのこと。せっかくなので試してみたいと思います。

測定方法

手元のMacでフィボナッチ数を計算する時間を計測しました。アルゴリズムはシンプルな再帰で、時間計測にはtimeコマンドのuserを用いています。
この頃 流行りの 言語たち(他)でベンチマーク (Dart, Go, Julia, Nim, Python, Rust 他) を参考にさせていただきました。

測定対象言語

VとC以外にもいくつかの言語で測定してみました。

  • C
  • Java
  • Go
  • PHP
  • JavaScript
  • V

コンパイル組とインタプリタ組が2, 3個あればいいかなという感じです。
今回はV言語を試したかっただけなので、選定基準も測定方法も適当です。もう少しちゃんとしたベンチマークに興味のある方はフィボナッチで各種言語をベンチマークfibonacci game あたりをご参照ください。

検証環境

MacBook Pro 13インチ 2016年モデル、Intel Core i7 2.4 GHz、メモリ16GB、macOS version 10.12.6です。

ソースコードと実行コマンド

細かいことはいいから結果だけ見たい!という方はベンチマーク結果をどうぞ。

C

まずはCから。gccのバージョンはこちら。

$ gcc -v
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 9.0.0 (clang-900.0.38)
Target: x86_64-apple-darwin16.7.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

clang…だと…?
Xcodeってgccという名のClangが入ってるんですね。

fib.c
#include <stdio.h>

int fib(int n) {
    if (n < 2) return n;
    return fib(n - 2) + fib(n - 1);
}

int main(void) {
    printf("%d\n", fib(42));
    return 0;
}

42番目のフィボナッチ数を標準出力に表示します。計算量多そうですね。

# 最適化オプションなし
$ gcc -o fib_c fib.c
$ time ./fib_c

# 最適化オプションあり
$ gcc -O3 -o fib_c_o3 fib.c
$ time ./fib_c_o3

最適化オプションのありなしで二種類計測してみました。

Java

Javaです。

$ java -version
java version "1.8.0_221"
Java(TM) SE Runtime Environment (build 1.8.0_221-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.221-b11, mixed mode)

たまたま手元に8があったのでこちらを使います。最新じゃなくてすみません。

fib.java
class fib {
    static int fib(int n) {
        if (n < 2) return n;
        return fib(n - 2) + fib(n - 1);
    }

    public static void main(String[] args) {
        System.out.println(fib(42));
    }
}
$ javac fib.java
$ time java fib

Go

$ go version
go version go1.12.7 darwin/amd64

最近流行りのGoです。V言語はGoリスペクトらしいので測定対象に入れました。実際、Vの文法はGoに酷似しています。goroutineとかまであります。

fib.go
package main

import "fmt"

func fib(n int) int {
    if n < 2 {
        return n
    }
    return fib(n-2) + fib(n-1)
}

func main() {
    fmt.Println(fib(42))
}
$ go build -o fib_go fib.go
$ time ./fib_go

PHP

インタプリタ組代表です。

$ php -v
PHP 5.6.30 (cli) (built: Oct 29 2017 20:30:32)
Copyright (c) 1997-2016 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies

PHPer各位に7系でやれと怒られそうですが、そもそもコンパイル組とは実行時間の桁が違うので誤差の範囲内かなと思いそのままやりました。今は反省している。

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

print fib(42);
time php fib.php

JavaScript

なんとなくJavaScriptも入れてみました。速そうだし。

$ node -v
v10.11.0

Node.jsです。

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

console.log(fib(42));
$ time node fib.js

V

お待ちかねのV言語です。

$ ./v -v
V 0.1.17

バージョン表示するコマンドがなんだか某難解言語のようですね。

fib.v
fn fib(n int) int {
    if n < 2 {
        return n
    }
    return fib(n-2) + fib(n-1)
}

fn main() {
    println(fib(42))
}

シンタックスハイライトが効きません。Qiita様よろしくお願い致します。
ソースコードの見た目はほぼGoですね。funcがfnになってるところがさらにモダンっぽいです。

# 最適化オプションなし
$ ./v -o fib_v fib.v
time ./fib_v

# 最適化オプションあり
$ ./v -o fib_v_prod -prod fib.v
time ./fib_v_prod

-prodをつけるとコンパイル時に最適化をしてくれるみたいなので、このオプションありとなしで計測してみました。

ベンチマーク結果

結果です。言語紹介と同じ順に並べてます。

言語 バージョン 実行時間
C clang 9.0.0 1.939s
C (-O3オプション) clang 9.0.0 1.596s
Java oracle jdk 1.8.0 1.200s
Go 1.12.7 1.938s
PHP 5.6 1m31.640s
JavaScript node 10.11.0 0m3.349s
V 0.1.17 1.943s
V (-prodオプション) 0.1.17 1.663s

上から順に眺めてみます。

C。最初のものを基準として考えればよさそうです。

Cの-O3オプション。結構速くなってますね。

Java。えっ!?速っ!! Cより速いのか…。JITの効果でしょうか、詳しくは分かりません。昔は「Java=遅い」的なディスをよく見かけたものですが、時代は変わりましたね。

Go。Cと同じくらい速いですね。良い。

PHP。遅っっ。 遅すぎて処理が止まったかと思いました。PHPが遅いというよりは、インタプリタとはこういうものなのでしょう。

JS。速っっ。 PHPの直後にやったのであまりの速さに腰抜かすかと思いました。コンパイル組に迫る勢い。V8最強すぎるな…

V。うん。Cと同じくらいですね。-prodつけたらちょっと速くなりますね。個人的にはJavaとJSの結果が衝撃的だったのでVの印象が薄れてしまいました。まあas fast as C の広告に偽りはないっぽかったのでよかったです。

まとめ

  • V言語はC言語と同じくらい速い
  • Javaめっちゃ速い
  • JavaScriptもめっちゃ速い

最後の方ほとんどV言語と関係なくなっちゃいましたけど、楽しかったのでなんでも良いです。
皆様もぜひV言語を試してみてください。