我有一个大约一百万个值的循环。我想只存储每个值的指数来显示它们,例如在直方图中。
目前我这样做:
int histogram[51]; //init all with 0
for(int i = 0; i < 1000000; i++)
{
int exponent = getExponent(getValue(i));
//getExponent(double value) gives the exponent(base 10)
//getValue(int i) gives the value for loop i
if(exponent > 25)
exponent = 25;
if(exponent < -25)
exponent = -25;
histogramm[exponent+25]++;
}
有更高效和优雅的方式吗?
也许没有使用数组?
答案 0 :(得分:1)
这样做是否有更高效和优雅的方式?
唯一更优雅的方法是使用Math.Min
和Math.Max
但不会更有效率。 histogramm[Math.Max(0,Math.Min(50,exponent+25))]++
字符较少,但我认为不再具有高性能或优雅。
也许没有使用数组?
数组是一组原始值,因此是最直接的存储方式。
答案 1 :(得分:1)
假设getExponent
和getValue
已经过优化,优化此选项的唯一方法是使用Parrallel.For
。我不认为差异会很大,但我认为这是唯一的方法。
对于数组,它是可用于存储数据的最佳索引低级数据结构。
使用并行库[using System.Threading.Tasks;
]:
int[] histogram = new int[51]; //init all with 0
Action<int> work = (i) =>
{
int exponent = getExponent(getValue(i));
//getExponent(double value) gives the exponent(base 10)
//getValue(int i) gives the value for loop i
if (exponent > 25)
exponent = 25;
if (exponent < -25)
exponent = -25;
histogram[exponent + 25]++;
};
Parallel.For(0, 1000000, work);
答案 2 :(得分:1)
使用条件和数组访问进行优化并不多。但是,如果getExponent函数是一项耗时的操作,则可以缓存结果。很多事情都取决于典型数据的样子。配置文件,看它是否有帮助。另外,有人提到使用Parallel。这也值得进行分析,因为如果getValue或getExponent足够慢以克服并行和锁定开销,它可能会有所不同。
重要提示:对于字典而言,使用double可能是一个坏主意。但是我对数学的进行以及从双人的转换到对话感到困惑。
无论哪种方式,这里的想法是缓存计算。所以如果这个测试证明有用,也许你可以找到更好的方法。
int[] histogram = Enumerable.Repeat(0, 51).ToArray();
...
Dictionary<double, int> cache = new Dictionary<double, int>(histogram.Length);
...
for (int i = 0; i < 1000000; i++)
{
double value = getValue(i);
int exponent;
if(!cache.TryGetValue(value, out exponent))
{
exponent = getExponent(value);
cache[value] = exponent;
}
if (exponent > 25)
exponent = 25;
else if (exponent < -25)
exponent = -25;
histogram[exponent + 25]++;
}
答案 3 :(得分:0)
尝试使用公共属性为您的指数存储值,因此可以测试并检查结果。
至于优雅,我会用实际的函数或子程序简化if
条件,并用清晰简洁的命名创建额外的抽象。