勝手に添削 (C vs Python vs Ruby vs Haskell(無意味な処理deベンチマーク))

なんか指名されたので、 C vs Python vs Ruby vs Haskell(無意味な処理deベンチマーク) このコードを Pythonic に書き直していきます。 ちなみに、 Python は 3.3 を使います。

まず、最初のコード

n = 4000
a = []
count = 1
for x in range(n):
    a.append([])
    for y in range(n):
        a[x].append(count)
        count += 1
list(map(lambda e: e.reverse(), a))
print(a[-1][-1])

time コマンドで実行速度測ったら 5.1sec でした。 さて、 Python はローカル変数とグローバル変数でアクセス速度が違います。(呼び出した関数の中などからグローバル変数を書き換えられる可能性はありますが、ローカル変数は外部から書き換えられる可能性がないからです)

なので、ループを行う処理は関数を作ってその中でやりましょう。

def main():
    n = 4000
    a = []
    count = 1
    for x in range(n):
        a.append([])
        for y in range(n):
            a[x].append(count)
            count += 1
    list(map(lambda e: e.reverse(), a))
    print(a[-1][-1])

main()

これで 2.8sec になりました。でも、このコードはあまり Pythonic ではありません。 Pythonic にしてみましょう。

def main():
    n = 4000
    a = []
    for c in range(1, 1+n**2, n):
        a.append(list(range(c, c+n)))
    for e in a:
        e.reverse()
    print(a[-1][-1])

main()

これで 0.65sec になりました。

このブログに乗せているコードは引用を除き CC0 1.0 で提供します。