【问题标题】:Global vs local variable efficiency in multiple function call多个函数调用中的全局变量与局部变量效率
【发布时间】:2015-09-26 22:57:29
【问题描述】:

首先需要注意的是,我知道过早的优化总是不好的。 第二个警告我对python相当陌生。

我正在读取数百万个数据块。每个块由 64 位组成,并保存在一个 numpy 数组中。为了对 numpy.uint64 类型进行位操作,所需的位移量也必须是相同的类型:numpy.uint64。

这可以通过转换数字或创建变量来完成。

number1 = numpy.uint64(80000)
shift_amount = numpy.uint64(8)
#option 1
number1 >> numpy.uint64(8)
#option2
number1 >> shift_amount

循环 10000 次并检查花费了多长时间。我假设 Option2 总是胜出,因为创建一个 numpy 整数的开销只完成一次。

我当前的程序为处理原始位的每个数据块调用一个函数。这个函数被调用了数百万次并附加了几个不同的列表。假设相同的想法并仅使用全局定义的值进行移位/位操作,则测试了另外两个循环条件。

def using_global(number1):
    global shift_amount
    number1 >> shift_amount

def using_local(number1):
    shift = np.uint64(54)
    number1 >> shift 

使用 global 循环这 10000 次函数总是快一个数量级。 问题:拥有一堆(10 多个)全局变量是不好的做法吗? https://wiki.python.org/moin/PythonSpeed/PerformanceTips 表示局部变量会更快。在这种情况下,我发现情况并非如此。我的主循环只是为数百万个数据字中的每个字调用该函数,因此这也可能效率低下。

【问题讨论】:

  • 您不需要global 从全局读取,只需写入即可。如果您适当地命名变量,我认为对于常量来说这不是一个坏主意。
  • 根本的区别是你只是在本地函数中创建 int,创建它大约需要函数总时间的 80%,所以它当然要慢很多
  • @ColonelThirtyTwo 感谢您的回复,实际上解决了很多问题。在这种情况下,我将继续从全局变量中读取它似乎是最有效的

标签: python loops numpy


【解决方案1】:

Python 不是为大量数字运算而设计的。 Numpy 相反。将所有数据垃圾放在一个 numpy 数组中。这比使用循环和单个函数调用要快得多:

values = numpy.ndarray(1000000, dtype=numpy.uint64)
# fill in the data
values >>= 8

如果你的班次取决于最高的半字节,例如,从 0 到 15 的半字节值有一个班次查找表:

shift_by_nibble = numpy.array([8,16,24,30,34,60,50,40,44,48,52,56,62,4,12,20], dtype=numpy.uint8)
values >>= shift_by_nibble[values>>60]

【讨论】:

  • 有趣的见解,尽管每个块需要根据顶部半字节移动不同的数量。
  • 请说明如何计算实际班次。您可能也可以将其矢量化。
  • 每个元素根据高半字节进行多位操作。然后,如果半字节匹配条件,则执行进一步的位操作并将它们的值存储在列表中。代码太长,无法在评论中添加,并且您似乎无法通过此站点发送消息。
  • @kaminsknator:看我的例子,这可能让你知道如何解决你自己的问题。
【解决方案2】:

using_global 引用一个全局变量。 using_local 引用了一个局部变量,但它还包括对 np.uint64() 的调用,这会影响性能。

【讨论】:

    【解决方案3】:

    除非我误解了这个问题,否则另一个有效的选择是将变量 shift_amount 传递给函数:

    def my_func(number1, shift_amount):
        return number1 >> shift_amount
    

    然后将函数调用为new_number = my_func(old_number, shift_amount)

    【讨论】:

    • 一个不错的选择,虽然传递一个函数 10 多个参数似乎很乱。测试该方法只比读取全局变量慢一点。仍然比显式声明局部变量快得多。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多