【发布时间】:2013-08-27 19:25:30
【问题描述】:
我有一个名为 Color 的类,它实现了以下覆盖:
public override Int32 GetHashCode()
{
unchecked
{
Int32 hash = 23;
hash = (hash * 37) + m_Changes.GetHashCode();
hash = (hash * 37) + m_Blue;
hash = (hash * 37) + m_Green;
hash = (hash * 37) + m_Random;
hash = (hash * 37) + m_RandomBlue;
hash = (hash * 37) + m_RandomGreen;
hash = (hash * 37) + m_RandomRed;
hash = (hash * 37) + m_Red;
return hash;
}
}
我正在尝试缓存结果以减少计算:
public static Color Average(Color left, Color right, Double weight)
{
Color value;
Int32 key = left.GetHashCode() ^ right.GetHashCode() ^ weight.GetHashCode();
if (!s_Averages.TryGetValue(key, out value))
{
Double complement = 100.0 - weight;
Int32 red = (Int32)(((left.Red * complement) + (right.Red * weight)) / 100.0);
Int32 green = (Int32)(((left.Green * complement) + (right.Green * weight)) / 100.0);
Int32 blue = (Int32)(((left.Blue * complement) + (right.Blue * weight)) / 100.0);
Int32 random = (Int32)(((left.Random * complement) + (right.Random * weight)) / 100.0);
Int32 randomRed = (Int32)(((left.RandomRed * complement) + (right.RandomRed * weight)) / 100.0);
Int32 randomGreen = (Int32)(((left.RandomGreen * complement) + (right.RandomGreen * weight)) / 100.0);
Int32 randomBlue = (Int32)(((left.RandomBlue * complement) + (right.RandomBlue * weight)) / 100.0);
value = new Color(red, green, blue, randomRed, randomGreen, randomBlue, random, (left.Changes || right.Changes));
s_Averages.Add(key, value);
}
return value;
}
结果不好,因为我在屏幕上绘制平均颜色时得到错误的像素。如果我将该方法恢复为无缓存版本,一切正常:
public static Color Average(Color left, Color right, Double weight)
{
Double complement = 100.0 - weight;
Int32 red = (Int32)(((left.Red * complement) + (right.Red * weight)) / 100.0);
Int32 green = (Int32)(((left.Green * complement) + (right.Green * weight)) / 100.0);
Int32 blue = (Int32)(((left.Blue * complement) + (right.Blue * weight)) / 100.0);
Int32 random = (Int32)(((left.Random * complement) + (right.Random * weight)) / 100.0);
Int32 randomRed = (Int32)(((left.RandomRed * complement) + (right.RandomRed * weight)) / 100.0);
Int32 randomGreen = (Int32)(((left.RandomGreen * complement) + (right.RandomGreen * weight)) / 100.0);
Int32 randomBlue = (Int32)(((left.RandomBlue * complement) + (right.RandomBlue * weight)) / 100.0);
return (new Color(red, green, blue, randomRed, randomGreen, randomBlue, random, (left.Changes || right.Changes)));
}
这只能意味着我使用 GetHashCode 生成的密钥不是唯一的。如何管理这种缓存,为我的颜色平均值获取唯一键?
【问题讨论】:
-
例如:为什么你认为这是一个合适且唯一的键?:Int32 key = left.GetHashCode() ^ right.GetHashCode() ^ weight.GetHashCode();
-
嗯,我不这么认为,从这产生了什么......这就是为什么我试图找到一个好的解决方案......
-
我感觉即使有缓存,哈希码计算和字典查找也可能不会让事情太快很多(除非你有 很多重复使用的颜色)。你有一个可衡量的瓶颈吗?另外,已经很晚了,所以我可能错了,但是您不能将
100.0从complement和weight预先划分一次而不是6 次吗? (即便如此,这是一个很小的优化) -
问题是我每 50 毫秒使用数百种颜色。渲染工作正常,但一开始,如果我不得不计算我需要用于该帧的所有颜色,一切都会变慢......这就是我试图缓存的原因。预分割是什么意思?
标签: c# .net caching dictionary hashcode