我有一个应用程序涉及一个可能非常大的数组集合(索引最大值为int
),但 lazy - 它们的内容被计算在飞行中,直到被要求才真正知道。数组也是不可变的 - 每个数组的每个元素的值在程序的整个生命周期中都是不变的。在某种意义上,数组是稀疏,通常只请求所有数组元素的一小部分(数组不包含大的零块,并且在这种意义上不是“稀疏的”。)
查找(并且可能在过程中计算)数组元素可能很昂贵,所以我想添加一个缓存层。缓存应该实现以下接口:
void point_cache_store (gpointer data, gsize idx, gdouble value);
gdouble point_cache_fetch (gpointer data, gsize idx);
其中data
作为每个数组的唯一句柄(可能有很多这样的句柄)。 point_cache_fetch()
应该使用相同的value
和point_cache_store()
参数返回传递给data
的{{1}}参数,或者通过返回特殊值{{1来指示缓存未命中(调用者永远不会使用idx
调用DATUM_UNKNOWN_VALUE
)。
问题是:如何实施point_cache_store
和DATUM_UNKNOWN_VALUE
? (它们目前是无操作存根。)
要考虑的要点:
point_cache_fetch()
或point_cache_store()
个参数调用point_cache_store()
或point_cache_fetch()
。data
也可以返回idx
。在这种情况下,调用者只会执行普通查找。point_cache_fetch()
和DATUM_UNKNOWN_VALUE
参数,调用者将始终提供相同的data
参数。我意识到有很多方法可以做到这一点,并且需要权衡利弊。但是,对于这个问题,我将通过一个非常具体的标准来评估答案:它们是否能够在激发该问题的应用程序中提高某个特定基准的性能。如果您想加倍努力并自己运行基准测试,请按以下步骤操作:
idx
函数value
和git clone git://github.com/gbenison/starparse
git clone git://github.com/gbenison/burrow-owl.git -b point-cache-base
可在“burrow / spectrum / point_cache.c”中找到。相关基准是“基准/ b_cache”。
答案 0 :(得分:0)
“非常大的稀疏懒数组”?听起来你需要hash table。
从你的point_cache_fetch
函数原型和所有问题中,我对你的缓存值是双精度数还是不可变数组感到困惑。
我不打算提供实施,因为这不是一个“编码挑战”网站。您应该尝试查找并重用现有的线程安全哈希表库,并根据您的特定需求比较它们的性能。