簡體   English   中英

優化python一線式

[英]Optimizing python one-liner

我對程序進行了概要分析,並且超過80%的時間都花在了這一單行功能上! 我該如何優化? 我正在與PyPy一起運行,所以我寧願不使用NumPy,但是由於我的程序幾乎所有時間都花在那上面,所以我認為為NumPy放棄PyPy可能是值得的。 但是,我更喜歡使用CFFI,因為它與PyPy更兼容。

#x, y, are lists of 1s and 0s. c_out is a positive int. bit is 1 or 0.
def findCarryIn(x, y, c_out, bit):

    return (2 * c_out +
            bit -
            sum(map(lambda x_bit, y_bit: x_bit & y_bit, x, reversed(y)))) #note this is basically a dot product.

可以肯定的是,使用numpy可以大大加快速度。 您可以這樣定義函數:

def find_carry_numpy(x, y, c_out, bit):
    return 2 * c_out + bit - np.sum(x & y[::-1])

創建一些隨機數據:

In [36]: n = 100; c = 15; bit = 1

In [37]: x_arr = np.random.rand(n) > 0.5

In [38]: y_arr = np.random.rand(n) > 0.5

In [39]: x_list = list(x_arr)

In [40]: y_list = list(y_arr)

檢查結果是否相同:

In [42]: find_carry_numpy(x_arr, y_arr, c, bit)
Out[42]: 10

In [43]: findCarryIn(x_list, y_list, c, bit)
Out[43]: 10

快速速度測試:

In [44]: timeit find_carry_numpy(x_arr, y_arr, c, bit)
10000 loops, best of 3: 19.6 µs per loop

In [45]: timeit findCarryIn(x_list, y_list, c, bit)
1000 loops, best of 3: 409 µs per loop

這樣您的速度提高了20倍! 將Python代碼轉換為Numpy時,這是非常典型的加速。

不使用Numpy,使用timeit測試之后,最快的求和方法(正在執行的操作)似乎是使用簡單的for循環並求和元素,示例-

def findCarryIn(x, y, c_out, bit):
    s = 0
    for i,j in zip(x, reversed(y)):
        s += i & j
    return (2 * c_out + bit - s)

盡管這並不能將性能提高很多(大約20%左右)。

時序測試的結果(使用不同的方法,包含上述方法的func4 )-

def func1(x,y):
    return sum(map(lambda x_bit, y_bit: x_bit & y_bit, x, reversed(y)))

def func2(x,y):
    return sum([i & j for i,j in zip(x,reversed(y))])

def func3(x,y):
    return sum(x[i] & y[-1-i] for i in range(min(len(x),len(y))))

def func4(x,y):
    s = 0
    for i,j in zip(x, reversed(y)):
        s += i & j
    return s

In [125]: %timeit func1(x,y)
100000 loops, best of 3: 3.02 µs per loop

In [126]: %timeit func2(x,y)
The slowest run took 6.42 times longer than the fastest. This could mean that an intermediate result is being cached
100000 loops, best of 3: 2.9 µs per loop

In [127]: %timeit func3(x,y)
100000 loops, best of 3: 4.31 µs per loop

In [128]: %timeit func4(x,y)
100000 loops, best of 3: 2.2 µs per loop

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM