关于类:python:使用staticmethod实现嵌套类的性能问题

Python: performance issue implemenating nested classes with staticmethod

请检查下面的示例工作代码:我们使用混合staticmethods实现nested classes

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import time

class A:
    def __init__(self):
        time.sleep(0.1)

    def a1(self):
        print 'a1'

    @staticmethod
    def a2():
        print 'a2'

    class B:
        @staticmethod
        def b2():
            A.a2()         #fine.  
            A().a1()       #very bad solution, computation cost is high !!!

        @staticmethod
        def x():
            t = time.clock()
            for i in xrange(100):
                A.B.b2()
            print 'elapsed: %0.1fs'%(time.clock()-t)

用作:

1
A.B.x()

上述方法是可行的,但正如您可能注意到的,在A().a1()行中,我们试图从容器类A访问非静态方法a1,计算成本太高。我们通过在A初始化中使用sleep来强调这一点。因此,您得到了这一点,例如,它可以是我们工作中所必需的任何耗时的初始化。因此,我们认为在上述行中实例化类A不是一个好的选择。如何不在上面例示A,而是像上面那样做。尽管相关问题包括这个和那个,但上面的问题已经在任何地方得到了解答。

编辑:我们对诸如why use it等建议不感兴趣。上面明确指出的我们感兴趣的问题是如何改进这一行

1
A().a1()

这就是全部。

根据Martijn Pieters给出的建议,按以下方式解决。我们之所以接受这个答案,是因为能说明解决问题的方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class B:
    @staticmethod
    def b2(Ai):
        A.a2()         #fine.
        if Ai is None: Ai = A()
        Ai.a1()        #now is fine.

    @staticmethod
    def x():
        t = time.clock()
        Ai = A()
        for i in xrange(100):
            A.B.b2(Ai=Ai)
        print 'elapsed: %0.1fs'%(time.clock()-t)

谢谢您。


您的问题与静态方法或嵌套类无关。全局函数也存在同样的问题:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class A:
    def __init__(self):
        time.sleep(0.1)

    def a1(self):
        print 'a1'

def a2():
    print 'a2'

def b2():
    a2()  
    A().a1()

def x():
    t = time.clock()
    for i in xrange(100):
        b2()
    print 'elapsed: %0.1fs'%(time.clock()-t)

调用x()仍然会导致在b2()之外的循环中创建昂贵的A()实例。

您需要设计一个缓存策略来创建A()。这里总结起来有太多的方法,当然在重用A()的实例时没有太多的信息,创建一个新实例是可以接受的。

如果您只想为x()中的循环重用A()的实例,那么将其作为可选参数传递:

1
2
3
4
5
6
7
8
9
10
11
12
def x():
    t = time.clock()
    instance = A()
    for i in xrange(100):
        b2(instance)
    print 'elapsed: %0.1fs'%(time.clock()-t)

def b2(instance=None):
    a2()
    if instance is None:
        instance = A()
    instance.a1()

现在,该实例在函数x()的持续时间内被缓存。