Python 为什么我的numpy.searchsorted比datetime列表中的bisect.bisect_性能差?

Python 为什么我的numpy.searchsorted比datetime列表中的bisect.bisect_性能差?,python,performance,numpy,Python,Performance,Numpy,我读到过numpy的searchsorted是比python的对分更快的二进制搜索。numpy需要更多的准备 我正在使用numpy.datetime64对象的numpy.array。这个性能测试类似于我的用例——为单个目标搜索大约1000个日期时间的列表 from bisect import bisect_left from datetime import datetime, timedelta from random import randrange from timeit import ti

我读到过numpy的searchsorted是比python的对分更快的二进制搜索。numpy需要更多的准备

我正在使用numpy.datetime64对象的numpy.array。这个性能测试类似于我的用例——为单个目标搜索大约1000个日期时间的列表

from bisect import bisect_left
from datetime import datetime, timedelta
from random import randrange
from timeit import timeit

import numpy as np


def randdate():
    r = randrange(int((datetime.max - datetime.min).total_seconds()))
    return datetime.min + timedelta(seconds=r)


data = sorted(randdate() for _ in xrange(1000))
np_data = np.array(data, dtype=np.datetime64)

x = randdate()
np_x = np.datetime64(x)


def python_bisect():
    result = bisect_left(data, x)
    return result


def numpy_searchsorted():
    result = np_data.searchsorted(np_x)
    return result


time1 = timeit(python_bisect, number=1000)
time2 = timeit(numpy_searchsorted, number=1000)
print time1
print time2
print "bisect/searchsorted: {}".format(time1 / time2)


不过,我发现对分的速度是searchsorted的两倍。

您的基准测试存在一些问题:

  • 应该对输入列表/数组进行排序
  • Python级别的
    for
    循环中的单个操作不是衡量NumPy性能的好方法:
    np.searchsorted
    的第二个参数支持数组。使用此功能
  • 使用更多的输入,例如
    10**6
    而不是
    20000
  • 使用
    timeit
    进行可靠的性能测量
  • 下面是一个演示:

    N = 10**6
    
    data = sorted([randdate() for _ in range(N)])
    np_data = np.sort(np.array(data, dtype=np.datetime64).astype(np.int64))
    
    def python_bisect():
        return [bisect(data, data[x]) for x in range(N)]
    
    def numpy_searchsorted():
        return np.searchsorted(np_data, np_data, side='right')
    
    %timeit python_bisect()       # 1.3 s per loop
    %timeit numpy_searchsorted()  # 60 ms per loop
    

    你在哪里整理你的数据?这些方法只有在对列表进行排序时才有效。numpy在一次对整个值数组进行排序时速度更快。当一个接一个地以Python循环的方式进行时,开销比对分要大得多。另外,您没有对相同的数据进行排序。很难比较我的用例我想用一个目标进行二进制搜索。我对数据进行了排序,二分法仍然稍微快一点。@Daniellon,当然,所以使用
    bisect
    。NumPy适用于基于矢量阵列的计算,但它不能保证加快单个计算。