プログラミング速度とプログラム速度

次のうちどちらのプログラムの方がより好ましいか。開発するプログラムはバッチ処理をするプログラムで22:00以降動かし,朝7:00までに結果が出れば良いものとする。

プログラムA:開発に6ヶ月掛かった。でも実行は1時間で終了する。たまに落ちる。

プログラムB:開発が1ヶ月で完了した。でも実行は10時間掛かる。プログラムは落ちない。

Aはアルゴリズムを工夫し,データ構造を工夫し,より高速に動作するようにプログラミングも工夫したため複雑さが増し安定性に欠けるものになってしまった。

Bはより早くプログラムを完成するため仕様に忠実にプログラムを作成した。しかし,Bは22:00以降に動かしても実行に10時間掛かり終了が朝8:00になってしまうので仕様を満たさない。

AとBのどちらが良いか。単純に考えればAはBの10倍の性能を持っている。Aの方が良いに決まっている。

昔(といっても桃太郎が出てくるような昔ではない,そんな時代にコンピュータは無い,80年代,90年代初頭位かな)は,高速に動作するプログラムが求められた。少々安定性が悪くてもより高速な処理が求められた。

しかし,現在はCPUスピードが高速になり,プログラムは高速に動作するより安定的に動作することが求められるようになってきたように感じる。

例えば,10時間掛かるプログラムでもCPU速度が2倍のマシンに入れ替えたら5時間で済む可能性がある。Bのマシンスペックを2倍にして,プログラム速度を2倍にする事を考える。

よってAよりBの方が求められるプログラムと言えるだろう。

例えば,次のような条件が加わったらどうだろう。

次の日までにプログラムを10本動かして結果を出さなければならない。

単純に考えれば1時間で終了するプログラムは10時間,10時間掛かるプログラムは100時間掛かることになる。マシンを幾ら高速にしても100時間を10時間にするにはちょっと厳しい。

こういう場合はAの方が良いと考えるか。

しかし,最近はマシンが安くなってきたので,こういう場合マシンを10台用意して並列に実行してしまうことを考える。

よってこのような場合でもBの方がより現実的なプログラムということが言える。

(例1)
私の所で1994年から続く仕事がある。その仕事はバッチ処理でデータ加工を行うのだが,94年当時は完了までに8時間以上掛かっていた。それが今では45分程度で終わってしまう。このプログラムはお客さんから全く見えず,高速に処理する必要が無かったのでプログラムを分割し,プログラム間のインタフェースをファイルにすることで安定的に動作するプログラム作成を心がけた。結果この方針は間違っていなかったと自負している。

(例2)
Windows3.1の頃アセンブラでギチギチに最適化したプログラムを作成した。そのプログラムは圧縮された図形を展開するのであるが,Cでプログラムするととてもで無いが実用的な速度で伸張する事が出来ず兎に角速度を求められていたのでアセンブラでギチギチにコードを組んだ。自慢じゃないが我ながら良くできた伸張プログラムだと思う。

やがて80486,Pentiumが登場し,Windowsも3.1からWindows95, Windows98 と進化を遂げていった。私の組んだプログラムはアセンブラをフル活用,リアルモードで動作するので,CPUが速くなってもプログラムは全然速くならないという世にも珍しいプログラムとなってしまった。セグメントレジスタさえも使い廻すという超アセンブラ最適化プログラムだったのでプロテクトモードにアップデートすることは諦め,Cで組み直した。その結果速度は問題なし。プログラムを32ビット版にしたたことさえ気づかないものだった。

こういう経験を踏まえるとやはりAよりBの方がプログラムとしては良いと感じてしまう。速いというのは機械の性能が速くなってしまえば取り柄が無くなってしまうことだから。

もちろんクリティカルな処理をする部分は高速に作らなければならないのは当たり前。クリティカルでなくても常識の範囲で高速化しなければならないのは当たり前。

円を描く笑い話

人から聞いた話で恐縮であるが,マシンが高速化するととんでもないプログラムをする人が出現するのである。

円を描くのは普通ライブラリにある円描画関数を使用するのであるが,ある人は

x = cosθ, y = sinθ

の公式を使ってθをループで廻し (x,y) に点を描いたということだ。CPU高速化の最大の弊害かな。

やっかいなのはお客さんがそのことを知らずに,開発者が「これが限界速度です」なんて言う場合である。

世の中高速化の需要はあるようだが,調べてみたら案外こんなのがネックになっていたりして。