0 . 概要
前回、「Nimのベンチ&サイズの最適化と比較」だったか、そういう記事を書いていましたが、
あれはあんまりよい記事ではなかった(なんというか詳しくなかった)ので、再投稿という形で投稿します。
(前回の記事はもう消す予定です)
このページでは、
1 : 最適化の方法と--optオプションの使い方
2 : それぞれの効果と比較
を説明します。
1 . 最適化の方法と--optオプションの使い方
最適化
$ nim c <file>
普段よく使う、動作確認での使用が想定された一番手っ取り早いビルドです。
ビルドが非常に早いように設定されていますが、これではベンチマークもバイナリサイズもメモリ消費も最悪です。
これを最適化するには、
$ nim c -d:release <file>
としましょう。
これが最も簡単な最適化です。
これでいつの日かブログのベンチマーク紹介ページで見た、あのNimの突っ走りが実現されます。
ただ、結果は最強なのですが、やはりビルド時間が Debug Build に比べ圧倒的に長いです。
opt
続いて、--optオプションを加えて最適化を行います。
(使うときは必ずReleaseにするみたいです)
$ nim c -d:release --opt:none <file>
$ nim c -d:release --opt:size <file>
$ nim c -d:release --opt:speed <file>
Nim Compiler User Guide によると ( 僕には英語の読解力が殆どないので本当かどうか定かではありませんが )
どうやら「最適化を全く行わない ( none ) か、ベンチマーク優先の最適化 ( speed ) 、バイナリサイズ優先の最適化 ( size ) のどちらかを行う」みたいです。
2 . それぞれの効果と比較
さて、上記で紹介したいくつかの最適化方法を比較してみます。
評価は「ビルド時間」「ベンチマーク」「バイナリサイズ」の4点を比較して行いました。
(今回は比較のために、モジュールの再構築を行う -f
オプションを使っています。)
比較用ソースコード
import times,math
var sins,coses,num : float64 = 0.0
let max = 10000000
let s = epochTime()
for i in 0..<max:
num = float64(i)
sins += num.sin
coses+= num.cos
echo epochTime()-s
echo sins
echo coses
0~10000000(1000万)の数字の正弦&余弦を計算し、それぞれを足し合わせて出力するプログラムです。
( 正接はなんとなくオーバーフローが怖かった )
最初に出力された数値(実質的な計算時間)が小さいほど処理が早いといえます。
結果
|ビルドの方式|ビルド時間 ( sec )|計算時間 ( sec )|バイナリサイズ ( KB )|
|:-:|:-:|:-:|:-:|:-:|
|Debug|2.984|2.6712|594|
|Release|5.218|2.6713|215|
|Release+none|2.671|2.2338|200|
|Release+size|2.767|1.9370|177|
|Release+speed|5.249|1.9527|215|
nim c -f
(18943 lines compiled; 2.984 sec total; 37.039MiB peakmem; Debug Build)
2.671246767044067sec
594KB
--
nim c -d:release -f
(18943 lines compiled; 5.218 sec total; 26.121MiB peakmem; Release Build)
1.95266604423523sec
215KB
--
nim c -d:release --opt:none -f
(18943 lines compiled; 2.671 sec total; 26.078MiB peakmem; Release Build)
2.233848571777344sec
200KB
--
nim c -d:release --opt:size -f
(18943 lines compiled; 2.767 sec total; 29.969MiB peakmem; Release Build)
1.937044143676758sec
177KB
--
nim c -d:release --opt:speed -f
(18943 lines compiled; 5.249 sec total; 26.078MiB peakmem; Release Build)
1.95266318321228sec
215KB
見解
まず一言。
Debug_Build ダメダメじゃん... ビルド時間が圧倒的に早い、ってことじゃなかったのか..?
ビルド時間はR+none、R+size、Debugがリード。中でも最も早いのが上記2つ。
ほかの2つは5秒もかかってしまった。
[ 検証外ではありますが、2回目以降のコンパイルはR+sizeが圧倒的に早く、続いてDebug、R+noneがリードしました。 ]
計算時間はR+size、R+speedが早いみたいです。Releaseだけではどうやら最強ではないみたい。
R+speed はベンチマークの最適化をするはずなんのに R+size と同値か...
バイナリサイズはやはりR+sizeが圧倒。Debug なかなか派手にやってる。
結果
とにかく、最適化するときは**--opt**を付けた方がいい。
動作確認するときも、**実は Debug よりも Release + opt のほうが効率的では??**なんて単純に思ってしまう結果に。
Debug 涙目...
実行環境
OS : Windows 10 Home
CPU : Intel Core i5-8250U (1.60GHz,4コア)
RAM : 8GB (PC4-19200 DDR4 SDRAM)
ストレージ : SSD (PCIe NVMe/M.2)
Nim : 1.18.0
最後に
最近、何ヶ月ぶりかに某くそ辛いラーメンを食べました。
めちゃくちゃうまかったです。
しかし、そのあとプリンを食べたら、お腹壊してしまいました。
酷く辛い物を食べた後に、酷く甘いものは食べないようにしましょう。身体がびっくりします。
あ、プリンもおいしかったです。