【问题标题】:Numpy: Negative Execution Time for exponentiation operationNumpy:求幂运算的负执行时间
【发布时间】:2016-12-28 15:51:13
【问题描述】:

我将两个大矩阵相乘,结果发现当我第一次对第一个输入执行求幂时运算速度更快:

import time
import numpy as np

a = np.asarray(np.random.uniform(-1,1, (100,40000)), dtype=np.float32)
b = np.asarray(np.random.uniform(-1,1, (40000,20000)), dtype=np.float32)

start = time.time()
d0 = np.dot(a,b)
print "\nA.B           - {:.2f} seconds".format((time.time()-start))

start = time.time()
d1 = np.dot(np.exp(a), b)
print "exp(A).B      - {:.2f} seconds".format((time.time()-start))

start = time.time()
d2 = np.dot(a, np.exp(b))
print "A.exp(B)      - {:.2f} seconds".format((time.time()-start))

start = time.time()
d3 = np.dot(np.exp(a), np.exp(b))
print "exp(A).exp(B) - {:.2f} seconds".format((time.time()-start))

结果如下:

A.B            1.27 seconds
exp(A).B       1.15 seconds
A.exp(B)       7.31 seconds
exp(A).exp(B)  7.38 seconds

谁能解释我做错了什么,或者这怎么可能?

【问题讨论】:

    标签: python numpy numeric execution-time exponentiation


    【解决方案1】:

    您所看到的原因是您在进行基准测试时永远不会只运行一次操作,这正是您在这里尝试的。当你只做一次时,很多事情都会影响你看到的结果。在这种情况下,可能会有一些缓存效果。此外,b 数组比 a 数组大得多,以至于在执行 np.exp(b) 时,您无法用 anp.exp(a) 得出任何结论,除非您在非常受控的环境中运行。

    为了更准确地对此进行基准测试,我们可以减少最后两个基准测试并专注于 aexp(a)。此外,我们重复操作 10,000 次并减小数组的大小以避免等待几分钟:

    import time
    import numpy as np
    
    a = np.asarray(np.random.uniform(-1,1, (100,400)), dtype=np.float32)
    b = np.asarray(np.random.uniform(-1,1, (400,2000)), dtype=np.float32)
    
    start = time.time()
    for i in xrange(10000):
        d0 = np.dot(a,b)
    print "\nA.B           - {:.2f} seconds".format((time.time()-start))
    
    start = time.time()
    for i in xrange(10000):
        d0 = np.dot(np.exp(a), b)
    print "exp(A).B      - {:.2f} seconds".format((time.time()-start))
    

    这会在我的计算机上产生以下结果:

    A.B           - 7.87 seconds
    exp(A).B      - 13.24 seconds
    

    如您所见,现在执行np.exp(a) 比访问a 需要更多时间,正如预期的那样。

    【讨论】:

      【解决方案2】:

      我怀疑这是内存缓存的问题,因为颠倒了执行顺序

      import time
      import numpy as np
      
      a = np.asarray(np.random.uniform(-1,1, (100,4000)), dtype=np.float32)
      b = np.asarray(np.random.uniform(-1,1, (4000,20000)), dtype=np.float32)
      
      start = time.time()
      d1 = np.dot(np.exp(a), b)
      print "exp(A).B      - {:.2f} seconds".format((time.time()-start))
      
      start = time.time()
      d0 = np.dot(a,b)
      print "A.B           - {:.2f} seconds".format((time.time()-start))
      
      start = time.time()
      d1 = np.dot(np.exp(a), b)
      print "exp(A).B      - {:.2f} seconds".format((time.time()-start))
      
      start = time.time()
      d0 = np.dot(a,b)
      print "A.B           - {:.2f} seconds".format((time.time()-start))
      

      仍然会导致第二个语句比第一个更快,但相同语句的第二次执行在第二次运行时也会更快。

      exp(A).B      - 0.72 seconds
      A.B           - 0.70 seconds
      exp(A).B      - 0.70 seconds
      A.B           - 0.69 seconds
      

      (我不得不减小数组的大小以避免内存问题。)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-12-31
        • 1970-01-01
        • 1970-01-01
        • 2015-06-10
        • 2016-10-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多