在 C++ 中缓存昂贵的数据 - 函数范围的静态与可变成员变量
我有一个相对昂贵的数据获取操作,我想缓存其结果。 此操作是从 const
方法调用的,大致如下:
double AdjustData(double d, int key) const {
double factor = LongRunningOperationToFetchFactor(key);
return factor * d;
}
我希望 AdjustData
保持 const
,但我想缓存该因子所以我只在第一次获取它。 目前我正在使用 mutable map
来存储结果(该映射是从 key
到 factor
),但是我认为使用函数范围的静态可能是一个更好的解决方案 - 这个因素仅由该函数需要,并且与类的其余部分无关。
这看起来是个好方法吗? 还有更好的选择吗? 我可能会考虑哪些事情,特别是在线程安全方面。
谢谢,
多姆
I've got a relatively expensive data-fetching operation that I want to cache the results of. This operation is called from const
methods, roughly like this:
double AdjustData(double d, int key) const {
double factor = LongRunningOperationToFetchFactor(key);
return factor * d;
}
I'd like AdjustData
to remain const
, but I want to cache out the factor so I only fetch it the first time. At present I'm using a mutable map<int, double>
to store the result (the map being from key
to factor
), but I'm thinking using a function-scoped static might be a better solution - this factor is only needed by this function, and is irrelevant to the rest of the class.
Does that seem like a good way to go? Are there any better options? What things might I think about, particularly with regard to thread-safety.
Thanks,
Dom
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我会用这样的东西包装 LongRunningOperationToFetchFactor 的实现。 我正在使用 Boost 作用域锁,但您也可以使用其他锁定框架进行类似的操作。
如果这确实是一个长时间运行的操作,那么锁定互斥体的成本应该是最小的。
您的问题不太清楚,但如果函数 LongRunningOperationToFetchFactor 是您类的成员函数,那么您希望该映射在同一类中成为可变映射。 不过,我使用单个静态互斥体进行访问仍然足够快。
I would wrap the implementation of LongRunningOperationToFetchFactor with something like this. I am using Boost scoped locks but you can so something similar with other locking frameworks.
If this really is a long running operation then the cost of locking the Mutex should be minimal.
It was not quite clear from you question but if the function LongRunningOperationToFetchFactor is a member function of you class then you want the map the be mutable map in that same class. I single static mutex for access is still fast enough though.
我不会将此缓存设为本地静态。 可变映射是缓存结果的解决方案。 否则,它将使您的函数毫无用处,因为您的类的不同对象将共享相同的缓存,因为所有对象的本地静态缓存都是相同的。 如果结果不依赖于对象,您可以使用局部静态。 但后来我会问自己,如果该函数不需要访问对象的任何状态,为什么它是对象的非静态成员。
正如您所说,它应该是线程安全的 - 如果不同的线程可以调用同一对象上的成员函数,您可能需要使用互斥体。
boost::thread
是一个很好用的库。I would not make this cache a local static. The mutable map is the solution for caching results. Otherwise it will make your function useless, as different objects of your class will share the same cache, as the local static cache is the same for all objects. You can use the local static if the result does not depend on the object though. But then i would ask myself why the function is a non-static member of your object, if it does not need to access any state of it.
As you say it should be thread-safe - if different threads can call the member function on the same object, you probably want to use a mutex.
boost::thread
is a good library to use.您可以使用单例模式(1) 来执行长时间运行的操作的类并缓存结果。 然后可以在其他类的 const 成员函数中使用该实例。 考虑互斥来保护映射数据结构的插入和提取,从而保证线程安全。 如果多线程性能是一个大问题,那么您可以将密钥标记为正在进行中,以防止多个线程同时计算同一密钥。
(1) 单例模式可能会被严重忽略。 所以,如果您是第一次看到它,请不要为它疯狂。
You can use the singleton pattern(1) to with a class that performs the long-running operation and caches the result. This instance could then be used in const member functions of other classes. Consider mutual exclusion to protect inserts and extractions from the map data structure for thread safety. If multi-threaded performance is a huge issue, then you can flag keys as in progress to prevent multiple threads from calculating the same key simultaneously.
(1) The singleton pattern can be grossly missed. So, please refrain from going crazy with it if you are seeing it for the first time.
除非我不明白,否则对我来说很明显你想将其设为静态:
这样你只获取一次因子。
Unless I don't understand, it seems obvious to me that you want to make this a static:
That way you only fetch the factor once.