【问题标题】:How to use a list of objects as map key in Groovy如何在 Groovy 中使用对象列表作为映射键
【发布时间】:2014-03-28 00:09:07
【问题描述】:

在我的 Groovy 应用程序中,我有一个每秒被调用多次的函数,所以我想让它尽可能快。这个函数接收一个对象列表,然后做一些魔术,并返回另一个列表。返回的列表内容取决于传递给函数的列表内容。

为了加快速度,我想缓存返回的列表,因为函数中的魔法不会经常改变。因此,在大约 99% 的调用中,此函数为相同的参数返回相同的列表。

为了实现这样的缓存,我想使用地图。此映射的键应该是函数输入参数中的列表,映射的值应该是函数为该输入列表返回的列表。

我的问题是:使用任意对象列表作为 Groovy 映射的键的最佳方式是什么?我想我可以遍历地图中的所有键,并逐项比较每个列表(地图的键)。但是那味道,我认为应该有更好更快的方法。

有什么想法吗?

【问题讨论】:

    标签: map groovy


    【解决方案1】:

    对于 Groovy 2.2.x,您可以将 @Memoized AST 用于在内部进行缓存的方法。

    @groovy.transform.Memoized
    List getMeList(List params) {
        println "params passed $params"
        params.reverse()
    }
    
    def paramsList = [1, 2, 4, 5, 6]
    getMeList(paramsList)
    getMeList(paramsList)
    getMeList(paramsList)
    getMeList(paramsList)
    
    def anotherList = ['a', 'b', 'c']
    getMeList(anotherList)
    getMeList(anotherList)
    getMeList(anotherList)
    getMeList(anotherList)
    

    当它在第一次调用该方法时只打印一次而其余调用的结果是从缓存中获取时,就会看到差异。

    【讨论】:

    • 哇,真的很棒,谢谢。但是有一个问题:我只需要在大多数情况下返回相同的列表,但不是全部。是否应返回缓存的值是在函数中确定的。那么有没有像条件Memoized这样的东西?
    • 只有注释可用的值是maxCacheSizeprotectedCacheSize,但是您可以使用该逻辑在此方法之外返回相同的列表,并在调用此记忆化方法之前进行检查,该方法执行只需要一次繁重的工作。
    【解决方案2】:

    所以我以调用hashCode() 作为输入参数列表结束。好消息是即使对于不同的列表,只要它们的内容相同,我也会得到相同的哈希值。这正是我想要的,而且我认为这是合理的快。

    【讨论】:

    • 这可能会产生问题。不保证hashCode 会相同。 This test will always fail.
    • 是的,我知道列表的顺序很重要。但就我而言,这很好,顺序不会改变。如果可以,那么将其缓存两次也可以...
    猜你喜欢
    • 2012-08-27
    • 2016-09-08
    • 1970-01-01
    • 2013-09-28
    • 1970-01-01
    • 2017-04-29
    • 2013-07-22
    • 2011-03-17
    相关资源
    最近更新 更多