0
1

一旦listに変換した方が高速?

Posted at

Python 3.10.11 を使って実験しました。

pythonにおいて、tuple, max, min, sumなどは、iterableを引数にできるため、

tuple(range(10))
max(range(10))
min(range(10))
sum(range(10))

のように書くことが可能だ。一方で、書き方としてtuple(list(range(10)))のように一旦listに変換してからtuplemaxを使っても文法上は問題ない。しかし、listへの変換が挟まるのだから微差とは言え遅くなるだろうと直観的には考えられる。

%%timeit
max(range(10000))
205 µs ± 8.12 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)
%%timeit
max(list(range(10000)))
221 µs ± 11.7 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)

これは直観通り。が、次のように書くと予想は裏切られる。

%%timeit
max(i for i in range(10000))
379 µs ± 30.9 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)
%%timeit
max([i for i in range(10000)])
247 µs ± 23 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)

いやいや、そんな書き方しないよ、と思うかもしれないが、こういうことはよくやる。

t = [(i, i + 1) for i in range(10000)]
%%timeit
max(i[0] for i in t)
591 µs ± 7.83 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)
%%timeit
max([i[0] for i in t])
514 µs ± 23.4 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)

やはり、一度listにした方が速い。

理由は不明。この計測方法だとキャッシュしてしまうのかと思ったが違うようだ。listはiteratorより優遇されているのかもしれないが、この結果はモヤる……

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1