在for循环期间计算特定事件的有效方法

时间:2016-07-06 19:44:51

标签: c# loops optimization histogram data-visualization

我有一个大约一百万个值的循环。我想只存储每个值的指数来显示它们,例如在直方图中。

目前我这样做:

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]++;
}

有更高效和优雅的方式吗?
也许没有使用数组?

4 个答案:

答案 0 :(得分:1)

  

这样做是否有更高效和优雅的方式?

唯一更优雅的方法是使用Math.MinMath.Max但不会更有效率。 histogramm[Math.Max(0,Math.Min(50,exponent+25))]++字符较少,但我认为不再具有高性能或优雅。

  

也许没有使用数组?

数组是一组原始值,因此是最直接的存储方式。

答案 1 :(得分:1)

假设getExponentgetValue已经过优化,优化此选项的唯一方法是使用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条件,并用清晰简洁的命名创建额外的抽象。