避免重新计算的计划

时间:2016-06-29 17:16:20

标签: python performance scala

动机:

为了抽象,我有一个处理对象列表的方法。这里我展示了一个简化版本用于说明目的(在这里使用Python2.7):

def foo(obj_lst, f):
    return list(map(f, obj_lst))

但是,对于某些情况,输入可能是foo([obj] * 1000, f),然后在函数调用中我必须重新计算1000次f(obj)。我们可以避免它,因为所有这些都是完全相同的对象。

我的解决方案:

我总是可以缓存计算结果,如

def foo2(obj_lst, f):
    cache_map = {}
    def foo_single(obj):
        if id(obj) not in cache_map:
            cache_map[id(obj)] = f(obj)
        return cache_map[id(obj)]
    result_lst = []
    for obj in obj_lst:
        result_lst.append(foo_single(obj))
    return result_lst

这完全是我想要的工作,它确实可以加快重新计算开销。

我的问题:

这个解决方案对我来说还不够,因为我必须在每个函数中手动执行此操作,是否有更好的解决方案来避免一般"同一对象重新计算"对于非随机函数?具有来自函数id和所有参数的键的全局cache_map似乎不起作用,因为对象id在其生命周期内仅是唯一的。

一般来说,我理解这在Python中可能没有多大意义,因为这些对象是可变的。请问在Scala等函数式编程语言中是否存在一些处理不可变对象问题的现有方案?谢谢!

2 个答案:

答案 0 :(得分:4)

您正在描述memoization

这可以通过creating your own helper/decorator function或使用标准库中的functools.lru_cache来实现(Python 3.2 +)

答案 1 :(得分:0)

或许这样的事情?

foo(objectsWithDupes, Memoized(f))

然后你可以做(​​除了其他用途)validateInput: function (inputValue, inputName, inputRules, setFormState, formFields) { let hasError = false; let errorText = false; if (!inputValue && inputRules.required) { hasError = true; errorText = 'This field is required.'; } else { hasError = false; errorText = false; }; state = { fields: Object.create(formFields) }; state.fields[inputName].hasError = hasError; state.fields[inputName].errorText = errorText; return setFormState(state); }