6
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

python2.7でリスト内包表記、for及びwhileの速度を計測してみた。

Posted at

初めに

リスト内表記、for及びwhileってどれが速いんじゃろ?と疑問を持ったので様々なコードを書いて計測してみた。

実行環境

python2.7
windows7
Intel Core i5 CPU 2.4GHz
メモリ 4.0 GB

測定対象

for 単独ループ(100万回)
for 2重ループ(1000回×1000回)
リスト内包表記(100万回)
リスト内包表記(1000回×1000回)
while 単独ループ(100万回)
while 2重ループ(1000回×1000回)

条件(詳しくは末尾のコード参照)

リストを作成する場合
 +forの場合(range有り無し)
+ループ内にif文がある場合
何らかの合計値を算出する場合
 +ループ内にif文がある場合

結果

単にリストを作るだけならリスト内包表記が最速だった。
if文が入ったりすると全体的にやや悪化し、forもリスト内包表記もあまり変わらなくなった。whileは2重ループで明らかに速度が落ちた。この理由はよくわからない。
合計値算出となると、リスト内包表記はforよりも遅くなった。これは100万個の和を取るsumに時間がかかっているということのように見える。
合計値算出+ifのところはリスト内包表記でもforでも変わらない結果となった。
determine.png

結論

とりあえずリスト内包表記を書いておけば良いが、作成したリストを活かさない処理(単にsumを取るだけなど)だと、当該リストを他の関数(sum()等)で処理するためのコストが増大して遅くなる可能性がある。
whileは多重ループのifに注意すると良さそう。

実験コードたち

seq1 = range(10**6)
seq2 = range(10**3)
num1 = 10**6
num2 = 10**3

v = 10**10
def for1():
  ls = []
  for i in seq1:
    ls.append(v)
  #print len(ls)

def for2():
  ls = []

  for i in seq2:
    for j in seq2:
      ls.append(v)
  #print len(ls)

def for_range1():
  ls = []
  for i in range(10**6):
    ls.append(v)
  #print len(ls)

def for_range2():
  ls = []
  for i in range(10**3):
    for j in range(10**3):
      ls.append(v)
  #print len(ls)
      
def for_listnai1():
  [v for i in seq1]

def for_listnai2():
  [v for i in seq2 for j in seq2]

def for_listnai_range1():
  [v for i in range(10**6)]

def for_listnai_range2():
  [v for i in range(10**3) for j in range(10**3)]

def forsum1():
  s = 0
  for i in seq1:
    s += v

def forsum2():
  s = 0
  for i in seq2:
    for j in seq2:
      s += v

def for_listnaisum1():
  sum([v for i in seq1])

def for_listnaisum2():
  sum([v for i in seq2 for j in seq2])

def while1():
  i = 0
  ls = []
  while i < num1:
    ls.append(v)
    i+=1
  
def while2():
  i = 0
  ls = []
  while i < num2:
    j = 0
    while j < num2:
      ls.append(v)
      j+=1
    i+=1

def whilesum1():
  i = 0
  s = 0
  while i < num1:
    s += v
    i+=1
  
def whilesum2():
  i = 0
  s = 0
  
  while i < num2:
    j = 0
    while j < num2:
      s += v
      j+=1
    i+=1
    
def forif1():
  ls = []
  for i in seq1:
    if v % 2:
      ls.append(v)

def forif2():
  ls = []
  for i in seq2:
    for j in seq2:
      if v % 2:
        ls.append(v)

def forlistnaiif1():
  [v for i in seq1 if v % 2]

def forlistnaiif2():
  [v for i in seq2 for j in seq2 if v % 2]

def whileif1():
  ls = []
  i=0
  while i <num1:
    ls.append(v)
    i+=1

def whileif2():
  ls = []
  i=0
  while i <num2:
    j=0
    while j<num2 :
      if v % 2:
        ls.append(v)
      j+=1
    i+=1
    
def forifsum1():
  s = 0
  for i in seq1:
    if v % 2:
      s+=v

def forifsum2():
  s = 0
  for i in seq2:
    for j in seq2:
      if v % 2:
        s+=v

def forlistnaiifsum1():
  sum([v for i in seq1 if v % 2])

def forlistnaiifsum2():
  sum([v for i in seq2 for j in seq2 if v % 2])

def whileifsum1():
  s = 0
  i=0
  while i <num1:
    s+=v
    i+=1

def whileifsum2():
  s=0
  i=0
  while i <num2:
    j=0
    while j<num2 :
      if v % 2:
        s+=v
      j+=1
    i+=1

時間測定コード


def exe(func,num=0):
    import time
    print "%s start:" % func
    s = 0
    for i in range(0,num): 
      start = time.time()
      exec func
      end = time.time()
      s += end - start
    print "%s finished: %d times." % (func,num)
    print s

if __name__=='__main__':
  exe("for1()",1)
  exe("for2()",1)
  exe("for_range1()",1)
  exe("for_range2()",1)
  exe("for_listnai1()",1)
  exe("for_listnai2()",1)
  exe("for_listnai_range1()",1)
  exe("for_listnai_range2()",1)
  exe("while1()",1)
  exe("while2()",1)
  
  exe("forsum1()",1)
  exe("forsum2()",1)
  exe("for_listnaisum1()",1)
  exe("for_listnaisum2()",1)
  exe("whilesum1()",1)
  exe("whilesum2()",1)

  exe("forif1()",1)
  exe("forif2()",1)
  exe("forlistnaiif1()",1)
  exe("forlistnaiif2()",1)
  exe("whileif1()",1)
  exe("whileif2()",1)

  exe("forifsum1()",1)
  exe("forifsum2()",1)
  exe("forlistnaiifsum1()",1)
  exe("forlistnaiifsum2()",1)
  exe("whileifsum1()",1)
  exe("whileifsum2()",1)
6
6
4

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
6
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?