意外な発見


◇忘れていたけれど

去年書いたFortranのコード。自分でもさっぱり覚えていないけれど、 友達のものと"はやさくらべ"をする機会があり、とんでもないミスに気づいた。 気づくのに一年を要したことになる。

◇ベンチマーク詳細

まず、1.csvから10000.csvまでのランダムなファイルを作る。中身は連立方程式を成す行列。

#!/usr/bin/python3
# Make random data
import random
import csv
for num in range(1,10001):
    dim = random.randint(2,10)
    arr = [[0 for i in range(dim+1)] for j in range(dim)]
    for col in range (0,dim):
        for row in range(0,dim+1):
            arr[col][row] = random.randint(-1000,1000)

    f = open(str(num)+'.csv', 'w')
    writer = csv.writer(f, lineterminator='\n')
    writer.writerows(arr)

次に、timeコマンドでで時間を測る。(出力はネックなので捨てている)

#!/bin/bash
time for i in `seq 1 10000`
do
  ./Simultaneous ./rnddata/$i.csv  >/dev/null 2>&1
done

自分の書いたものは異常なほど時間がかかっていた。(自分がuser:30sec、友達は2sec位)なぜだろう??

◇ミス

探しているうちに、次のような行があった。

        do ex_m=piv,d
            do ex_n=piv,d
                if(abs(linior(ex_m,ex_n))==maxval(abs(linior(piv:d,piv:d)))) then
                    ...

この最終行こそが戦犯で、コストの重い計算をdo文の中で繰り返していたので遅かったのだった。 maxval(abs(linior(piv:d,piv:d)))はループ中では変わらないのでループ外で一度計算すれば良い。 ああ、ショック。はずかし。これを修正したらまともな時間で動くようになった。

過去の自分の書いた文章なりスクリプトなりは 見なおしたほうが良い、という教訓を得た。

もどる


かもめ - Make / Walk / Others / About