python - 长参数列表和性能

标签 python performance global

这肯定不是特定于 python 的问题,但我正在寻找特定于 python 的答案 - 如果有的话。它是将带有大量变量的代码块放入函数(或类似的?)中。让我假设这段代码

##!/usr/bin/env python
# many variables: built in types, custom made objects, you name it.
# Let n be a 'substantial' number, say 47.
x1 = v1
x2 = v2
...
xn = vn

# several layers of flow control, for brevity only 2 loops
for i1 in range(ri1):
    for i2 in range(ri2):
        y1 = f1(i1,i2)
        y2 = f2(i1,i2)
        # Now, several lines of work

        do_some_work

        # involving HEAVY usage and FREQUENT (say several 10**3 times)
        # access to all of x1,...xn, (and maybe y1,y2)
        # One of the main points is that slowing down access to x1,...,xn
        # will turn into a severe bottleneck for the performance of the code.


# now other things happen. These may or may not involve modification
# of x1,...xn

# some place later in the code, again, several layers of flow control,
# not necessarily identical to the first occur
for j1 in range(rj1):
    y1 = g1(j1)
    y2 = g2(j1)
    # Now, again

    do_some_work  # <---- this is EXACTLY THE SAME code block as above

# a.s.o.

显然我想将“do_some_work”放入函数之类的东西中(或者可能更好?)。

在 python 中执行此操作的最高效方法是什么

  • 没有使用大量令人困惑的参数的函数调用

  • 无需性能有损地间接访问 x1,...,xn(例如,通过将它们包装到另一个列表、类或类似内容中)

  • 不使用 x1,...,xn 作为函数 do_some_work(...) 中的全局变量

我必须承认,我总是发现自己又回到了全局。

最佳答案

一个简单而肮脏的(可能不是最佳的)基准:

import timeit
def test_no_func():
    (x0,x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12,x13,x14,x15,x16,x17,x18,x19) = range(20)
    for i1 in xrange(100):
            for i2 in xrange(100):
                    for i3 in xrange(100):
                            results = [x0+x1+x2+x3+x4+x5+x6 for _ in xrange(100)]
                            results.extend(x7+x8+x9+x10+x11+x12+x13+x14+x15 for _ in xrange(100))
                            results.extend(x16+x17+x18+x19+x0 for _ in xrange(500))
    for j1 in xrange(100):
            for j2 in xrange(100):
                    for i3 in xrange(100):
                            results = [x0+x1+x2+x3+x4+x5+x6 for _ in xrange(100)]
                            results.extend(x7+x8+x9+x10+x11+x12+x13+x14+x15 for _ in xrange(100))
                            results.extend(x16+x17+x18+x19+x0 for _ in xrange(500))


def your_func(x_vars):
    # of the number is not too big you can simply unpack.
    # 150 is a bit too much for unpacking...
    (x0,x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12,x13,x14,x15,x16,x17,x18,x19) = x_vars

    results = [x0+x1+x2+x3+x4+x5+x6 for _ in xrange(100)]
    results.extend(x7+x8+x9+x10+x11+x12+x13+x14+x15 for _ in xrange(100))
    results.extend(x16+x17+x18+x19+x0 for _ in xrange(500))
    return results


def test_func():
    (x0,x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12,x13,x14,x15,x16,x17,x18,x19) = range(20)
    for i1 in xrange(100):
            for i2 in xrange(100):
                    for i3 in xrange(100):
                            results = your_func(val for key,val in locals().copy().iteritems() if key.startswith('x'))
    for j1 in xrange(100):
            for j2 in xrange(100):
                    for i3 in xrange(100):
                            results = your_func(val for key,val in locals().copy().iteritems() if key.startswith('x'))


print timeit.timeit('test_no_func()', 'from __main__ import test_no_func', number=1)
print timeit.timeit('test_func()', 'from __main__ import test_func, your_func', number=1)

结果:

214.810357094
227.490054131

传递参数的速度大约慢 5%。但也许您无法比引入 100 万次函数调用做得更好......

关于python - 长参数列表和性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12385278/

相关文章:

python - py2exe:错误:libzmq.pyd:没有那个文件或目录

python - Numpy 整数数组 : Find indices of multiple target ints

python - numpy 中的 set_printoptions() 错误

java - 自动执行 jprofiler 分析并保存快照

c - 静态全局变量和函数内部静态变量的区别

c - 在运行时重新初始化全局/静态内存或对全局/静态变量进行静态分析

python - 删除不重复的行 n 次

performance - 为什么 Chrome 审核建议我最小化 cookie 大小?

java - 按名称有效访问字段

php - 神秘的 JavaScript 变量变化