Pypy与Python中计数算法性能优化(Numpy vs List)

2024-06-16 10:15:59 发布

您现在位置:Python中文网/ 问答频道 /正文

我的预期是pypyy可以比python快一个数量级,但是结果表明pypy实际上比预期的慢。在

我有两个问题:

  1. 为什么pypy和numpy的速度明显较慢?在
  2. 我能做些什么来优化我的算法使pypyy(或python)更快?在

结果时间:

Python 2.7.5

  • #积分:16777216(8**3*32**3)
  • X范围时间:1487.15毫秒
  • Xrange Numpy时间:2553.98毫秒
  • 点生成时间:6162.23毫秒
  • 新一代时间:13894.73毫秒

Pypy 2.2.1版

  • #积分:16777216(8**3*32**3)
  • X范围时间:129.48毫秒
  • Xrange Numpy时间:4644.12毫秒
  • 点生成时间:4643.82毫秒
  • Numpy Gen时间:44168.98毫秒

算法

我用一个简单的算法在空间中生成一个点的列表,并试图优化算法。在

def generate(size=32, point=(0, 0, 0), width=32):
    """
    generate points in space around a center point with a specific width and
      number of divisions (size)
    """
    X, Y, Z = point
    half = width * 0.5
    delta = width
    scale = width / size
    offset = scale * 0.5
    X = X + offset - half
    Y = Y + offset - half
    Z = Z + offset - half
    for x in xrange(size):
        x = (x * scale) + X
        for y in xrange(size):
            y = (y * scale) + Y
            for z in xrange(size):
                z = (z * scale) + Z
                yield (x, y, z)

在优化方面,我开始考虑使用pypy而不是python。在比较这两种情况时,我想到了一些不同的情况:

  • 使用xrange计数

    rsize = 8    # size of region
    csize = 32   # size of chunk
    number_of_points = rsize ** 3 * csize ** 3
    [x for x in xrange(number_of_points)]
    
  • 使用xrange和numpy进行计数

    rsize = 8    # size of region
    csize = 32   # size of chunk
    number_of_points = rsize ** 3 * csize ** 3
    np.array([x for x in xrange(number_of_points)])
    
  • 用上面的算法运行

    rsize = 8    # size of region
    csize = 32   # size of chunk
    [p
     for rp in generate(size=rsize, width=rsize*csize)
     for p in generate(size=csize, width=csize, point=rp)]
    
  • 用numpy运行上面的算法

    rsize = 8    # size of region
    csize = 32   # size of chunk
    np.array([p
     for rp in generate(size=rsize, width=rsize*csize)
     for p in generate(size=csize, width=csize, point=rp)])
    

背景:

我正在尝试创建一个体素引擎,我想优化我的算法,以降低生成时间到一个可管理的水平。虽然我显然不会达到任何接近java/C++的东西,但我还是想尽可能地推Python(或pypy)。在

我注意到,列表查找比字典查找要快得多。列表也比元组快(出乎意料),尽管元组生成得更快。Numpy的读取时间甚至比非Numpy更快。但是,numpy的创建时间可以慢几个数量级。在

所以,如果阅读是最重要的,那么使用numpy有明显的优势。然而,如果阅读和创造同等重要,那么一个简单的清单可能是最好的。也就是说,我没有一个干净的方法来观察内存使用情况,但是我怀疑列表的内存效率远远低于元组或numpy。 另外,虽然这只是一个小的区别,但我发现.使用字典要比使用UuGetItem调用快一些(例如dictionary[lookup]vs。双亲。得到(查找))

时间安排。。。在

Python 2.7.5

阅读

 - Option 1: tuple access... 2045.51 ms
 - Option 2: tuple access (again)... 2081.97 ms    # sampling effect of cache
 - Option 3: list access... 2072.09 ms
 - Option 4: dict access... 3436.53 ms
 - Option 5: iterable creation... N/A
 - Option 6: numpy array... 1752.44 ms

创造

 - Option 1: tuple creation... 690.36 ms
 - Option 2: tuple creation (again)... 716.49 ms    # sampling effect of cache
 - Option 3: list creation... 684.28 ms
 - Option 4: dict creation... 1498.94 ms
 - Option 5: iterable creation...  0.01 ms
 - Option 6: numpy creation... 3514.25 ms

Pypy 2.2.1版

阅读

 - Option 1: tuple access... 243.34 ms
 - Option 2: tuple access (again)... 246.51 ms    # sampling effect of cache
 - Option 3: list access... 139.65 ms
 - Option 4: dict access... 454.65 ms
 - Option 5: iterable creation... N/A
 - Option 6: numpy array... 21.60 ms

创造

 - Option 1: tuple creation... 1016.27 ms
 - Option 2: tuple creation (again)... 1063.50 ms    # sampling effect of cache
 - Option 3: list creation... 365.98 ms
 - Option 4: dict creation... 2258.44 ms
 - Option 5: iterable creation...  0.00 ms
 - Option 6: numpy creation... 12514.20 ms

在所有的例子中,随机查找都是针对随机数据生成的。在

dsize = 10 ** 7   # or 10 million data points
data = [(i, random.random()*dsize)
         for i in range(dsize)]
lookup = tuple(int(random.random()*dsize) for i in range(dsize))

循环非常简单:

for x in lookup:
    data_of_specific_type[x]

而特定类型的数据是将数据转换为该类型(例如元组(data)、列表(data)等)


Tags: ofinnumpy算法forsizeaccess时间
1条回答
网友
1楼 · 发布于 2024-06-16 10:15:59

问题的一部分是:

np.array([p
    for rp in generate(size=rsize, width=rsize*csize)
    for p in generate(size=csize, width=csize, point=rp)])

完成创建list并将其转换为np.array的所有工作。在

更快的方法是:

^{pr2}$

相关问题 更多 >