【问题标题】:Optimizing dictionary loop summing values优化字典循环求和值
【发布时间】:2018-12-31 20:30:23
【问题描述】:

我有一个采用嵌套字典input_dict的方法

final = 0
for key, value in input_dict[self.state][self.city].iteritems():
    age = self._get_age(key)
    if (age > 0 and age < MAX_VAL):
      final += value  * self.lookup[key][age] * self.multiplier

return final

这在大约 0.03 秒内运行,但考虑到在示例执行中它被调用 >10k 次,它最终成为瓶颈并负责大约 50% 的运行时间。假设我不能减少调用该方法的总次数,有没有人有关于如何改进这个的建议?

【问题讨论】:

  • 正确。这是 2.7
  • self._get_age(key) 是做什么的?
  • 约会period: return (self.current_period - period) / 7
  • 句号的关键在哪里?
  • input_dict 的键是日期,因此每个键都是 self._get_age(key) 的参数

标签: python algorithm performance optimization python-2.x


【解决方案1】:

也许考虑类似以下的事情-

current_period = self.current_period - (self.current_period % 7)
MIN_VALUE = current_period - 7 * MAX_VALUE
return self.multiplier * sum(value * self.lookup[key][self._get_age(key)]
    for key, value in input_dict[self.state][self.city].iteritems()
    if MIN_VALUE < key < current_period
)

在这里,我将乘法 self.multiplier 拉出循环,并将比较 0 &lt; age &lt; MAX_VALUE 替换为预先计算值的等效比较,通过将 age 替换为 cmets 中描述的 _get_age() 方法获得并求解为key。这允许我们在age &lt;= 0 or age &gt;= MAX_VALUE 的情况下跳过函数调用+额外的计算,并且不会在原始0 &lt; age &lt; MAX_VALUE 上产生额外的成本(除了计算循环外的2个变量)。此外,这允许我们使用内置的 sum() 函数,该函数通常比通过 for 循环求和更快,但无需像 qxz 的回答那样创建单独的生成器。

请注意,我假设您的_get_age() 方法中的(self.current_period - period) 是一个整数,因此/ 7 将结果置于Python-2.x 中。如果不是这种情况,请从 current_period 分配中删除 - (self.current_period % 7) 以获得等效功能。

【讨论】:

    【解决方案2】:

    built-in sum function 通常比写出for 循环更快。 (请参阅this question。)在您的情况下,您可以构造要求和的值的generator expression,然后将其传递给sum

    items = (
        (key,value,self._get_age(key))
        for key,value in input_dict[self.state][self.city].iteritems()
    )
    return sum(
        value * self.lookup[key][age] * self.multiplier
        for key,value,age in items
        if 0 < age < MAX_VAL
    )
    

    【讨论】:

    • 我相信你可以使用链式比较,不知道会不会更快,但更pythonic
    • 嗯,sum 在内置数据类型上使用时通常很快,生成器表达式通常很慢。我敢打赌 for 循环会更快。
    • 也许用列表理解替换生成器表达式会更快?
    • 这不能很好地扩展,您必须构建一个列表。尽管我认为即使是中等规模的列表大小也会更快,例如几千甚至一万。但是,然后您将线性空间复杂度添加到可以占用恒定空间的事物中。可能不是问题...
    猜你喜欢
    • 1970-01-01
    • 2018-12-24
    • 1970-01-01
    • 1970-01-01
    • 2013-09-02
    • 2014-11-09
    • 2020-06-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多