python中uint8函数_NumPy性能:uint8对float和乘法对除法?

我刚刚注意到,我的脚本执行时间几乎减半,只需将乘法改为除法。在

为了调查这一点,我写了一个小例子:import numpy as np

import timeit

# uint8 array

arr1 = np.random.randint(0, high=256, size=(100, 100), dtype=np.uint8)

# float32 array

arr2 = np.random.rand(100, 100).astype(np.float32)

arr2 *= 255.0

def arrmult(a):

"""

mult, read-write iterator

"""

b = a.copy()

for item in np.nditer(b, op_flags=["readwrite"]):

item[...] = (item + 5) * 0.5

def arrmult2(a):

"""

mult, index iterator

"""

b = a.copy()

for i, j in np.ndindex(b.shape):

b[i, j] = (b[i, j] + 5) * 0.5

def arrmult3(a):

"""

mult, vectorized

"""

b = a.copy()

b = (b + 5) * 0.5

def arrdiv(a):

"""

div, read-write iterator

"""

b = a.copy()

for item in np.nditer(b, op_flags=["readwrite"]):

item[...] = (item + 5) / 2

def arrdiv2(a):

"""

div, index iterator

"""

b = a.copy()

for i, j in np.ndindex(b.shape):

b[i, j] = (b[i, j] + 5) / 2

def arrdiv3(a):

"""

div, vectorized

"""

b = a.copy()

b = (b + 5) / 2

def print_time(name, t):

print("{: <10}: {: >6.4f}s".format(name, t))

timeit_iterations = 100

print("uint8 arrays")

print_time("arrmult", timeit.timeit("arrmult(arr1)", "from __main__ import arrmult, arr1", number=timeit_iterations))

print_time("arrmult2", timeit.timeit("arrmult2(arr1)", "from __main__ import arrmult2, arr1", number=timeit_iterations))

print_time("arrmult3", timeit.timeit("arrmult3(arr1)", "from __main__ import arrmult3, arr1", number=timeit_iterations))

print_time("arrdiv", timeit.timeit("arrdiv(arr1)", "from __main__ import arrdiv, arr1", number=timeit_iterations))

print_time("arrdiv2", timeit.timeit("arrdiv2(arr1)", "from __main__ import arrdiv2, arr1", number=timeit_iterations))

print_time("arrdiv3", timeit.timeit("arrdiv3(arr1)", "from __main__ import arrdiv3, arr1", number=timeit_iterations))

print("\nfloat32 arrays")

print_time("arrmult", timeit.timeit("arrmult(arr2)", "from __main__ import arrmult, arr2", number=timeit_iterations))

print_time("arrmult2", timeit.timeit("arrmult2(arr2)", "from __main__ import arrmult2, arr2", number=timeit_iterations))

print_time("arrmult3", timeit.timeit("arrmult3(arr2)", "from __main__ import arrmult3, arr2", number=timeit_iterations))

print_time("arrdiv", timeit.timeit("arrdiv(arr2)", "from __main__ import arrdiv, arr2", number=timeit_iterations))

print_time("arrdiv2", timeit.timeit("arrdiv2(arr2)", "from __main__ import arrdiv2, arr2", number=timeit_iterations))

print_time("arrdiv3", timeit.timeit("arrdiv3(arr2)", "from __main__ import arrdiv3, arr2", number=timeit_iterations))

这将打印以下计时:

^{pr2}$

我一直认为乘法在计算上比除法便宜。然而,对于uint8来说,除法的效果几乎是前者的两倍。这是否与* 0.5必须计算浮点乘法,然后将结果转换回整数?在

至少对于float,乘法似乎比除法快。这通常是真的吗?在

为什么uint8中的乘法比float32中的乘法更膨胀?我以为8位无符号整数应该比32位浮点运算快得多?!在

有人能“解开”这个谜团吗?在

编辑:为了获得更多的数据,我还包括了向量化函数(如建议的),并添加了索引迭代器。矢量化的函数要快得多,因此不具有真正的可比性。然而,如果向量化函数的timeit_iterations设置得更高,则uint8和{}的乘法速度更快。我想这更让人困惑?!在

也许乘法实际上总是比除法快,但是for循环的主要性能漏洞不是算术运算,而是循环本身。尽管这并不能解释为什么循环在不同的操作中表现不同。在

EDIT2:如@jotasi所述,我们正在寻找division与{}和{}(或{})与{}(或{})的完整解释。此外,解释矢量化方法和迭代器的不同趋势也很有趣,因为在矢量化的情况下,除法似乎比较慢,而在迭代器的情况下则更快。在

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值