[0 0] = [0]なぜはるかに遅いよりa.insert(0,0)ですか?

ヒープオーバーフロー:

リストの使い方insert機能は、スライスの割り当てを使用するよりもはるかに遅いです。

> python -m timeit -n 100000 -s "a=[]" "a.insert(0,0)"
100000 loops, best of 5: 19.2 usec per loop

> python -m timeit -n 100000 -s "a=[]" "a[0:0]=[0]"
100000 loops, best of 5: 6.78 usec per loop

(注a空始まりますが、10万個の要素に成長します。)

最初に私に多分それはそれは無視できる程度だとオーバーヘッドまたはその属性検索や関数呼び出しだが、最後のショーの近くに挿入すると思いました:

> python -m timeit -n 100000 -s "a=[]" "a.insert(-1,0)"
100000 loops, best of 5: 79.1 nsec per loop

なぜ、「単一の要素の挿入」おそらく単純な専用の機能はそんなに遅いですか?

私もそれを再現することができrepl.itで

from timeit import repeat

for _ in range(3):
  for stmt in 'a.insert(0,0)', 'a[0:0]=[0]', 'a.insert(-1,0)':
    t = min(repeat(stmt, 'a=[]', number=10**5))
    print('%.6f' % t, stmt)
  print()

# Example output:
#
# 4.803514 a.insert(0,0)
# 1.807832 a[0:0]=[0]
# 0.012533 a.insert(-1,0)
#
# 4.967313 a.insert(0,0)
# 1.821665 a[0:0]=[0]
# 0.012738 a.insert(-1,0)
#
# 5.694100 a.insert(0,0)
# 1.899940 a[0:0]=[0]
# 0.012664 a.insert(-1,0)

repl.itが現在のPython 3.8.1を使用している間に私は、Python 3.8.2を使用しています。

user2357112はモニカをサポートしています。

私はそれは、彼らが使用することを忘れてしまっただけのことだろうと思うmemmoveの中でlist.insertあなたが見てみましょう場合は、コード list.insertの要素をシフトするために使用する、あなたはそれだけで、マニュアルループだ見ることができます。

for (i = n; --i >= where; )
    items[i+1] = items[i];

しばらくlist.__setitem__スライス割り当てパス上の用途memmove

memmove(&item[ihigh+d], &item[ihigh],
    (k - ihigh)*sizeof(PyObject *));

memmove 一般的な最適化の多くは、このようなSSE / AVX命令を生かして、その中に入れています。

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=16500&siteId=1