0
0

More than 1 year has passed since last update.

Pythonでの両端キュー(deque)

Posted at

概要

  • listの先頭要素削除の処理(pop(0))の時間はlistの長さの二乗で増加
    • pop(0)はlistの全要素を1つずつ前にずらすので、要素全体を再代入する必要があるため
  • collectionsモジュールのdequeクラスは両端キュー
    • 要素を先頭または末尾に追加、削除するときに定数時間演算で可能
  • 先頭要素に対して追加、削除を実施する処理を行う場合はdequeの使用を推奨
  • 今回の実装での測定結果(pop処理を先頭要素に100000回実施)
対象 時間
list 2.245
deque 0.111

list

list_example.py
#!/usr/bin/env python3
# -*- coding: utf_8 -*-
"""listの処理時間計測
"""

from cProfile import Profile
from pstats import Stats


def all_pop(array):
    for _ in range(len(array)):
        array.pop(0)


if __name__ == "__main__":
    # プロファイラに渡す用意
    array = list(range(100000))
    test = lambda: all_pop(array)

    # プロファイラの生成
    profiler = Profile()
    profiler.runcall(test)

    # 性能についての統計情報の取り出し
    stats = Stats(profiler)
    stats.strip_dirs()
    stats.sort_stats("cumulative")
    stats.print_stats()

$ python list_example.py
         100004 function calls in 2.302 seconds

   Ordered by: cumulative time

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000    2.302    2.302 example.py:24(<lambda>)
        1    0.056    0.056    2.302    2.302 example.py:16(all_pop)
   100000    2.245    0.000    2.245    0.000 {method 'pop' of 'list' objects}
        1    0.000    0.000    0.000    0.000 {built-in method builtins.len}
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}

deque

deque_example.py
#!/usr/bin/env python3
# -*- coding: utf_8 -*-
"""dequeの処理時間計測
"""

from collections import deque
from cProfile import Profile
from pstats import Stats


def all_pop(array):
    for _ in range(len(array)):
        array.popleft()


if __name__ == "__main__":
    # プロファイラに渡す用意
    array = deque(range(100000))
    test = lambda: all_pop(array)

    # プロファイラの生成
    profiler = Profile()
    profiler.runcall(test)

    # 性能についての統計情報の取り出し
    stats = Stats(profiler)
    stats.strip_dirs()
    stats.sort_stats("cumulative")
    stats.print_stats()

$ python deque_example.py
         1000004 function calls in 0.394 seconds

   Ordered by: cumulative time

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000    0.394    0.394 example.py:23(<lambda>)
        1    0.283    0.283    0.394    0.394 example.py:15(all_pop)
  1000000    0.111    0.000    0.111    0.000 {method 'popleft' of 'collections.deque' objects}
        1    0.000    0.000    0.000    0.000 {built-in method builtins.len}
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}

diff

example.py
--- list_example.py
+++ deque_example.py
@@ -1,24 +1,25 @@
 #!/usr/bin/env python3
 # -*- coding: utf_8 -*-
-"""listの処理時間計測
+"""dequeの処理時間計測
 """
 
+from collections import deque
 from cProfile import Profile
 from pstats import Stats
 
 
 def all_pop(array):
     for _ in range(len(array)):
-        array.pop(0)
+        array.popleft()
 
 
 if __name__ == "__main__":
     # プロファイラに渡す用意
-    array = list(range(100000))
+    array = deque(range(100000))
     test = lambda: all_pop(array)
 
     # プロファイラの生成

参考

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