为什么处理排序数组的速度不比Python中的未排序数组快?

时间:2012-10-11 15:05:37

标签: python performance

在这篇文章Why is processing a sorted array faster than random array中,它表示分支预测是排序数组性能提升的原因。

但我只是尝试使用Python的例子;我认为排序和随机数组之间没有区别(我尝试了bytearray和数组;并使用line_profile来分析计算)。

我错过了什么吗?

这是我的代码:

from array import array
import random
array_size = 1024
loop_cnt = 1000
# I also tried 'array', and it's almost the same
a = bytearray(array_size)
for i in xrange(array_size):
    a.append(random.randint(0, 255))
#sorted                                                                         
a = sorted(a)
@profile
def computation():
    sum = 0
    for i in xrange(loop_cnt):
        for j in xrange(size):
            if a[j] >= 128:
                sum += a[j]

computation()
print 'done'

5 个答案:

答案 0 :(得分:19)

我可能错了,但我看到链接问题与您的示例之间存在根本区别:Python解释字节码,C ++编译为本机代码。

if直接转换为cmp / jl序列的C ++代码中,CPU分支预测器可将其视为单个“预测点”,特定于此周期。

在Python中,比较实际上是几个函数调用,因此有(1)更多的开销;(2)我认为执行该比较的代码是用于每个其他整数比较的解释器的函数 - 所以它是“预测”斑点“不是特定于当前块,这使分支预测器更难以正确猜测。


编辑:另外,如this论文所述,解释器中有更多的间接分支,因此Python代码中的这种优化可能会被分支埋没翻译本身的错误预测。

答案 1 :(得分:5)

有两个原因:

  • 您的数组太小,无法显示效果。
  • Python比C有更多的开销,所以整体效果不太明显。

答案 2 :(得分:5)

我将原始代码移植到Python并使用PyPy运行它。我可以确认排序的数组比未排序的数组处理得更快,并且无分支方法也可以消除具有类似于排序数组的运行时间的分支。我相信这是因为PyPy是一个JIT编译器,所以正在进行分支预测。

[编辑]

这是我使用的代码:

import random
import time

def runme(data):
  sum = 0
  start = time.time()

  for i in xrange(100000):
    for c in data:
      if c >= 128:
        sum += c

  end = time.time()
  print end - start
  print sum

def runme_branchless(data):
  sum = 0
  start = time.time()

  for i in xrange(100000):
    for c in data:
      t = (c - 128) >> 31
      sum += ~t & c

  end = time.time()
  print end - start
  print sum

data = list()

for i in xrange(32768):
  data.append(random.randint(0, 256))

sorted_data = sorted(data)
runme(sorted_data)
runme(data)
runme_branchless(sorted_data)
runme_branchless(data)

答案 3 :(得分:4)

sorted()返回已排序的数组,而不是按位排序。你实际上是在两次测量相同的数组。

答案 4 :(得分:-3)

点击here查看更多答案和类似问题。数据排序时性能大幅提升的原因是分支预测惩罚被删除,正如Mysticial的回答中所解释的那样。