对这段代码进行分析,发现大部分时间都用在了日志操作上。有没有其他更高效的Python 3写法呢?使用列表推导式代替循环或者使用map函数因为需要使用lambda表达式而导致效率更低。
def log_total(data):
total = 0.0
log = log(data)
for i in range(10000):
total += log/(i+1)
return total
谢谢!
对这段代码进行分析,发现大部分时间都用在了日志操作上。有没有其他更高效的Python 3写法呢?使用列表推导式代替循环或者使用map函数因为需要使用lambda表达式而导致效率更低。
def log_total(data):
total = 0.0
log = log(data)
for i in range(10000):
total += log/(i+1)
return total
谢谢!
我建议你把log
从求和式中提取出来并缓存你的求和结果:
harmonic_series = sum(1. / i for i in range(1, 10001)) # Thanks, @mgilson
def log_total(data):
return log(data) * harmonic_series
log
,它仍然会被调用 10,000 次,因此每次都会产生巨大的成本,特别是当您实际上使用静态变量但在每次调用方法时计算它时。下一步将是使用其他问题中提到的 memmoization
从函数中获得更快的速度。 - sean(1./np.arange(1,10001)).sum()
对我来说可以将其缩短约6倍,但不是那么懒惰。 - mgilson1+1/2+1/3+...+1/10000
的总和是不变的,应该从循环函数中提取出来。也许一个妥协是将其作为log_total的默认参数包含在内,这样它就只会在编译时计算一次,而不是在每次调用log_total时都计算。) - PaulMcGlambda
,像这样:total = lambda data: log(data) * sum(1.0 / i for i in xrange(1, 10001))
我使用的是Python 2.7.3
。
10000
个元素的列表(尝试将10001
更改为1000000001
并查看发生了什么),这将占用大量RAM。 - Blender1.0/i
或者使用from __future__ import division
,否则你的总和将等于1+0+0+0+...
。 - PaulMcG谢谢!
我学习了 from__future__ import division
。 - user1389938
for i in range(1,10001): total += log/i
- mgilsonlog
函数是从math
模块中来的吗?如果是,那么我怀疑你直接改进它的性能可能会有困难(因为它是一个用 C 实现的内置函数)。如果log
是你自己编写的,那么可能还有改进的空间,但在我们提出建议之前,你需要展示它的代码! - Blckknghtdef log_total(data,log=log):
,这样可以使log
函数的查找局限于您的函数而不是全局命名空间。但是,这只是一个相当微小的加速,只有在您能够证明它确实有所作用时才应该使用(然后需要大量的文档说明正在发生什么)。 - mgilson