我必须保留一个双值缓存。使用后,它应该无效。两种选择
一种是在缓存值良好时添加布尔标志true
,在使用时将其设置为false
,当flag为false时,重新计算并重新填充。
第二个更有趣 - 我可以将它保持为double值并使用NaN作为无效/需要重新标记。
double get() const {
if (!isnan(_value)) {
double t = _value;
_value = std::numeric_limits<double>::quiet_NaN;
return t;
}
}
对此有何异议?对效率的任何想法?
答案 0 :(得分:6)
使用布尔值,否则当你的计算结果实际上变成NaN(由于计算)时,你将会遇到一些有趣的问题/错误。如果您依赖NaN作为“我已经使用过该值”的信号,那么在“有效”未使用的NaN的情况下,您将无法区分。
更不用说这样的语义重载将导致未来的代码读者(即使是你自己从现在开始的几个月)试图破译那些聪明的用法。 ; - )
通常,重载变量的含义是一种不好的做法。起初看起来可能很可爱,但它不可避免地会造成更多伤害。
就效率而言 - 我真的建议你先测量,然后再担心优化。我敢打赌,一旦你运行测试,你会发现速度差异远低于CPU温度波动引起的性能噪音。
答案 1 :(得分:3)
我怀疑效率会有所不同,但带有布尔标志的代码会更具可读性:
double get() const {
if (!_cached)
_value = recalculate();
_cached = !_cached;
return _value;
}
答案 2 :(得分:0)
我认为值得指出的是,nan可以是更有效的解决方案,最大的优势在于您使用的内存少于标记(由于对齐,其开销可能超过每个双字节1个字节) )。这意味着如果你需要读取大量内存,它也可能会更快。
应该指出的另一件事是IEEE nans可以有不同的值。他们的指数必须是全部,但尾数可以是除了全零之外的任何东西。这意味着您可以使用&#34;特殊&#34; nan用于区分计算结果,或者如果需要一个包含两个以上状态的标志,则使用不同类型的nans。