LoginSignup
5
1

More than 3 years have passed since last update.

盛れる!ベンチマーク!

Posted at

はじめに

TwitterでD言語の日本語情報増やしたいなーとか言っていたところ、タイミングよく文字列操作で良い記事があったのでちょっと読んでいました。

Pythonも速いんだなーとか思いつつ、この言語の並びならD言語が1番じゃない…?と思ったので、ベンチマーク部分について軽く追試しつつ盛れるだけ盛ってやろうと思った次第です。(盛ってはいけない)

ちなみに比較対象は、元から結果が上位だった Python(pypy3) と JavaScript(Node) に絞りますのでご了承ください
(たまたま手元で計測が容易だったものともいう)

前置き

計測にあたり元のソースコードは何も変更していませんのでベースはそちら参照してください。
https://github.com/yosgspec/splits

pypy3やnodeの引数は詳しくないので最適化っぽいものは何もやっていません。

というか言語のタイプが違いすぎるのであまり意味のある比較ではないという認識はあります。
それでもそれなりに肉薄してるので、これはそういうコンテンツなのだと思っていただければ幸いです。

何度でも書くけどネタ記事だよ!

計測

諸々書いてしまうと盛れないので先に結果発表です。

結果

  • 傾向だけ見れればいいかということで、元のコードをローカル環境でそれぞれ10回計測しました
  • 元々各言語で3種類の結果がありましたが、そのなかで一番速かったパターンを採用しています
  • D言語はdmdとldc2という2つのコンパイラで実行しています

結果を表にまとめると以下の通りでした。
単位はミリ秒(msecs)で、????というのが盛ったやつです。詳細は後述します。

結果データ

# dmd ldc2 pypy3 Node dmd + ???? ldc2 + ????
1 335 174 198 272 78 0
2 297 166 195 280 87 0
3 301 184 194 274 81 0
4 298 198 199 273 88 0
5 297 173 192 279 79 0
6 298 174 198 275 79 0
7 302 176 201 275 80 0
8 297 171 195 286 78 0
9 315 179 193 282 84 0
10 295 178 198 287 88 0

集計値

dmd ldc2 pypy3 Node dmd + ???? ldc2 + ????
平均 303.5 177.3 196.3 278.3 82.2 0
中央値 298 175 196.5 277 80.5 0
最大値 335 198 201 287 78 0
最小値 295 166 192 272 88 0
標準偏差 12.44 6.60 2.91 5.38 4.16 0

盛らなくてもldc2が速かった!
そして盛ったdmdは速かったpypy3より倍以上速い!ldc2に至っては無限倍速い!すごい!!!
(素のdmd…お前…負けたんか…)

補足

  • pypy3では splitlines より replacesplit の組み合わせの方が速かったのでそちらを採用しました
    • 単純なsplitelines のほうは平均で約370msecsでした。元記事より遅いのでなんか変ですね?そういうもの?

計測方法

環境

使ったのは Surface Book2 の Windows10 環境です。

CPUは、 第 8 世代 インテル® Core™ i7-8650U クアッド コア プロセッサ、4.2GHz Max Turbo
スペック:https://www.microsoft.com/ja-jp/p/surface-book-2/8mcpzjjcc98c?activetab=pivot:techspecstab

D言語

主要なコンパイラが3つありますが、今回は公式コンパイラのdmdとLLVMベースのldc2の2つを使います。
語弊がありますが、dmdはビルドが速い公式コンパイラ、ldc2はLLVMベースの実行が速いコンパイラです。

ちなみにどちらも2019年7月6日時点でそれぞれ最新版です。

dmd

バージョン
dmd --version
DMD32 D Compiler v2.087.0

Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved written by Walter Bright
実行コマンド
dmd splits_d.d -O -release -inline -boundscheck=off
app.exe

LDC

バージョン
ldc2 --version
LDC - the LLVM D compiler (1.16.0):
  based on DMD v2.086.1 and LLVM 8.0.0
  built with LDC - the LLVM D compiler (1.16.0)
  Default target: x86_64-pc-windows-msvc
  Host CPU: skylake
  http://dlang.org - http://wiki.dlang.org/LDC
実行コマンド
ldc2 splits_d.d -O3 -release -boundscheck=off
app.exe

Node

2019/07/06時点のLTS版 v10.16.0 です。最新版は試していません。

バージョン
node --version
v10.16.0
実行コマンド
node splits.js

Python(pypy3)

Windows向けのpypy3を拾ってきて使いました。

バージョン
pypy3 --version

Python 3.6.1 (784b254d6699, Apr 16 2019, 12:10:48)
[PyPy 7.1.1-beta0 with MSC v.1910 32 bit]
実行コマンド
pypy3 splits.py

ベンチマークを盛る

盛るっていうよりなんだこれ?という結果ですが、何をしたかといえばD言語の特徴である CTFE(コンパイル時関数評価)です。

D言語の関数には通称 CTFEable と呼ばれる分類があり、一定の条件を満たすとコンパイル時に計算を実行でき、結果を定数として保持できます。
C++でも constexpr がありますし、ぼちぼちメジャーな機能ではあります。

CTFEable な任意の式は定数として保持できるので、この手のベンチマークならちょっと書き換えるだけで実行時間はほぼゼロになるだろう、という魂胆です。
(というかdmdはなんでゼロにならないんでしょうかね…?)

やったこと

というわけで書き換えたのは2行です。変数宣言と計算のところをenumにするだけ。

変更前
auto words = "asdff\nastgrw3h\r\nwtegole\rkserlhge3t\nearsgh\nergh\rsagr\r\nerghe\r";
// 中略
wordList = words.splitLines();
変更後
enum words = "asdff\nastgrw3h\r\nwtegole\rkserlhge3t\nearsgh\nergh\rsagr\r\nerghe\r";
// 中略
enum temp = words.splitLines();
wordList = temp;

まとめ

  • 盛らなくてもD言語が1番速かった(よかった…)
    • 改行で分割するのは std.stringsplitLines で安定。
    • ベンチマークを書くときは変に気を回す必要なし
      • enumやグローバル変数の初期化式を書かない限りCTFEされない(条件は公式ドキュメントに書いてありそう)
      • コンパイル時に評価することを期待する場合、enumで1回変数に落とすのが確実
  • pypy3はやはり速い。JITは正義。
  • NodeのRegexは正規表現の中では異様に速い…裏で何かやってそう…
  • pypy3もNodeも処理単体で見れば普通にdmdより速い(まじか)

あとがき

ぶっちゃけD言語のCTFEは「任意の式がCTFEできるかどうかチェックして、できるならやる」という仕組みだと思っていました。
なので最初にソース見たときの感想は「なんでこれで実行時間測れてるの?」です。

今回の結果から、ちゃんとCTFEするにはenumに1回入れる必要があることがわかりました。

「ベンチマークしたいときは普通に書いておけば大丈夫」ということですが、逆に言えば「何かの式で一部がCTFEされることはない」ので「定数っぽいところは1回enum挟んだほうが無難」ということになりそうです。(要追試)

ローカルのプログラムをいくつか見てみたところ、長い式を普通に書いてるところが結構見つかったので、要所にenum挟んでやればまだまだ速くできる余地がありそうです。

というわけでいろいろがんばっていきます!

5
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
5
1