【问题标题】:Store past results of a function存储函数的过去结果
【发布时间】:2020-01-14 01:17:20
【问题描述】:

我有一个函数,它接收两个数组,进行一些计算,然后返回一个新数组。该函数可能被调用 60,000 次(或 500k,具体取决于),其中高达 25% 的调用次数是在重做先前的计算。

prev_calc = {}
def arrayMagic(ar1,ar2):
    ar1_t = tuple(ar1)
    ar2_t = tuple(ar2)

    if (ar1_t,ar2_t) in prev_calc: 
        return prev_calc[(ar1_t,ar2_t)]
    #some somewhat, but not too expensive function
    res = magicCalc(ar1,ar2)

    prev_calc[(ar1_t,ar2_t)] = res

    return res

ar1 和 ar2 分别是 3 个浮点数的数组;例如:[1.1,1.2,2.2] res 也是一个包含 3 个浮点数的数组。

问题在于元组转换和字典查找恰好与magicCalc() 函数所用的时间非常接近。由于这是我代码中的主要瓶颈,因此优化它会解决很多问题。该函数传递了两个数组,所以我不能将它们作为一个数组。

有没有一种快速的方法来存储函数过去的结果并返回它们?

【问题讨论】:

  • The problem is that the tuple conversion and dictionary lookup happen to be very close to the time the magicCalc() function takes.这是什么意思?
  • @information_interchange magicCalc 花费的时间不是很长,但也不能忽略。基本上跳过字典存储所花费的时间与我实现它之后的时间相同。因此,如果这是存储函数结果的最快方法,那么我就完成了,因为两种方法都接近相同的速度。如果有更快的方法,那我就受益了。
  • 您能否详细介绍一下ar1ar2 是什么? numpy 数组?多大?
  • retval = prev_calc.get((ar1, ar2)); if retval != None: return retval 意味着您不会进行两次查找(一次用于in 条件,第二次用于return)。也就是说,我通常避免为性能关键代码选择 Python。
  • 另外——如果你还没有通过分析器运行这段代码,我强烈推荐它。理想情况下,可以密切关注垃圾收集器正在做什么。

标签: python ironpython


【解决方案1】:

这似乎很快......

d = dict()
l1 = [1.1,21.1,31.1,41.1,51.1]
l2 = [12.1,21.1,31.1,41.1,51.1]


def do(a1):
    cacheKey = str(a1) 
    if cacheKey in d:
        print("Read from cache")
        return d[cacheKey]
    else:
        print("calc and cache result")
        d[cacheKey] = sum(a1)
        return d[cacheKey]

print(do(l1))
print(do(l2))
print(do(l1))

【讨论】:

  • 如何测量? print()s 将比这里的其他任何东西都慢,慢到足以控制任何测量的时间。
  • 打印语句仅作为示例。这里真正的问题是如何最好地散列一个数组以缓存它。鉴于数组中只有 3 个浮点数,将其转换为字符串应该不会那么昂贵。没有进行实际测量。
  • 如果你想断言str(somelist)tuple(somelist) 快,基准测试是为了支持它。如果这是真的,我会非常感到惊讶。
  • ideone.com/gCZahY -- tuple(l)str(l) 快 20 倍以上。
猜你喜欢
  • 1970-01-01
  • 2016-07-03
  • 1970-01-01
  • 1970-01-01
  • 2010-10-24
  • 1970-01-01
  • 2012-11-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多