- 北の空からみなみへ -
exblog staff

<< 実用的ワンライナー(スタートア... コマンドプロンプトの1行ベンチマーク >>
1 line FizzBuzz benchmark
2018年 03月 19日

1行FizzBuzzの千回ループベンチを、仕事終わりの帰りがけに最遅のマシンにもう一度走らせてみた。
すると、(うっかり表示を垂れ流したとはいえ)140msという遅さを叩き出した。
そういえば、Celeronのこのマシンと、core i3の2台には、Microsoft Office がインストール済みだった。
いかにも疑わしい。これは再確認しておきたい。

それとともに、マシンの違いによる速度差と、コードの中身でのそれとを比較したくて、最初コード最後のものとでベンチをやり直してみました。
まさかofficeをアンインストールするわけにもいかず、前回ベンチを取った時と同じく再起動しての実行です。

やっている途中で速度がばらつき、出力をnulにしないで表示をさせてみると、たまにひっかかっている感じになりました。
あれ?これって、もしかしたらバックグラウンドプロセスの影響かな?
そこでネットから切り離して、Defenderのリアルタイム監視をを停止したら、速度は上がりました。

そういえば、業務側は最小限のウイルス対策で済むよう物理的に外部と切り離し、セキュアに保っていたのでした。(アンチウイルスソフトは入っているが、当初稼働のtm社はオーバーヘッド大きすぎて、より軽いm社のものだし、いまではサポート切れでサーバのウイルスデータベースの更新も停止)
そういう意味では、前回取得していたのはマシン性能よりもバックグラウンド負荷のベンチマークだった。こう言えるかも知れない。

んでやってみたけっかはっぴょう。旧コード(文字変数逐次書き換え版)の出力on と off、最終コード(計算分岐最小限のリスト展開版)で 出力off と on です。
c0062295_20245588.gif

ふむふむ。表示のON/OFFでは、8~9ms程度の差。数文字x百行程度の文字出力では、負荷のほうはそれほどではない。
けれども、コード差では3倍の速度差。。
やはり除算(剰余)はプログラムの速度低下の要素なのですね。
(IF文もそうらしいが、このコードでその差は大きくない。むしろ変数の部分書き換え多用が元凶か。)

あとでまたやり直したくなった時に、効率的にできるように手順をメモ


最初に、CMD/v:on でコマンドプロンプトを起動(具体的には次のコマンド入力)
color f0&cmd/v:on/k"prompt $g &title Celeron G1620 2.7GHz"

回数をセット
set $count=1000

次に新旧FizzBuzzのコード引数を、変数FizzBuzzとして代入

こちら新の方
set FizzBuzz="for /L %a in (0,1,6) do for %A in (1 2 Fi 4 Bu Fi 7 8 Fi Bu 11 Fi 13 14 FizzBu) do if %a11==6%A (exit) else if %A gtr a (echo.%Azz) else set/a $=15*%a+%A&echo."
こちら旧のほう
set FizzBuzz="for /L %A in (1,1,100) do (set/a I=%A%3,Z=%A%5>nul&(for %B in (!I!) do set I=!I:~%B,1!)&for %B in (!Z!) do set Z=!Z:~%B,1!)&set $= &(if defined I set $=!$!Fizz)&(if defined Z set $=!$!Buzz)&set $=!$:~1!&(if not defined $ set $=%A)&echo !$!"

ベンチマークを実行 (%FizzBuzz% 直後の閉じカッコ直後に >nul を出し入れて表示を on/off)
(for /L %z in (1,1,!$count!) do cmd/q/v:on/c%FizzBuzz%)>nul&set etime=!time!&set/p<nul=%time%-!etime!/!$count!Loop Average = &set/a ltime=((1000*(3600*!etime:~0,2!+60*(1!etime:~3,2!-100)+1!etime:~6,2!-100)+1!etime:~-2!0-1000-(1000*(3600*%time:~0,2%+60*(1%time:~3,2%-100)+1%time:~6,2%-100)+1%time:~-2%0-1000))+86400000)%86400000/!$count!&echo ms




今回、ちょうどまるっと引用符で囲んでしまったことで、cmd.exeへ渡す引数の変数化は容易だった。

入力の容易さから、引用符付きで変数に代入したのだけれども、本来的には引用符がない形で変数に入れた方が使い勝手もいいし後からコードを見ても、どこまでが変数であるかが明確になる。

1文字変数であれば、%~1 のような引用符削除方があるので、ここは for文を(反復ではなく)変数代入装置として使ってしまえばいい。
既に引用符つき変数となってるから、
for %1 in (%FizzBuzz%) do set FizzBuzz=%~1
と置けば、ベンチマーク側で、
cmd/q/v:on/c"%FizzBuzz%"
と書けるから、パラメータの範囲がより明らかだ。

ところで、パラメータと引数って同様な意味合いで使える気がする。
ほとんど同じででもニュアンスが異なるバンド と ベルト(あーこれ、前々前回のオリンピック/パラリンピックの年だな)の例もあるし、調べて考えることにしました。
調べた過程で、こちらがとても参考になりました。

パラメータと引数の違い

自分なりにまとめた結果、

  • パラメータは英文で、FORMAL parameter とも呼ばれ、訳語は引数。これは受け渡し変数のイメージ。(識別子と言うそうな)
  • 引数の方は、ACTUAL argument で、こちらは引数。盛り付けられた料理でいうなら、胃袋に入る中味と言うのかな、
  • parameter の語は、プロシージャ(本質同一だが、呼び出し受ける function / subroutine 側とも言える)がメッセージを受け取るために用意する、「受け皿変数」の名前。
  • argument の語は、呼び出したプロシージャに渡す変数の「中味」。調理で言えば食材(もしくは差し出される料理そのもの)

  • 実例的に考えるなら
  • 年齢計算式プログラムという関数に渡すパラメータは、生年月日,算出日(省略可:略時は現在日付)。
  • 年齢計算式を呼び出すメインルーチンが、用意するのは S01.12.24 といった引数 。(食あたり=エラーで吐き出しそうな例示を 汗)

  • パラメータ(受取り変数名)は、プログラムコードの一部分。調理器具で言えば投入口。
  • ARGUMENT(実引数=入力値=インプット)は、食材そのもの。
この分類で言えば、コードの挙動を設定する/オプションスイッチは、パーシャル引数とでも言えるだろうか。(材料ではなく設定つまみだから、パラメータのニュアンスが強そうではある)

下手な説明よりもこちらの一読が早いかも。(日本語のサイトです)

SyntaxError: missing formal parameter - JavaScript | MDN


[PR]
by bucmacoto | 2018-03-19 02:49 | quote/data | Trackback | Comments(0)
トラックバックURL : https://bucmac.exblog.jp/tb/29376641
トラックバックする(会員専用) [ヘルプ]
名前
URL
画像認証
削除用パスワード
<< 実用的ワンライナー(スタートア... コマンドプロンプトの1行ベンチマーク >>
<< 実用的ワンライナー(スタートア... コマンドプロンプトの1行ベンチマーク >>