【问题标题】:.net for loop performance issue.net for 循环性能问题
【发布时间】:2015-05-28 07:43:15
【问题描述】:

我有这个代码:

namespace FrequencyGeneratorConsoleApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            Thread.CurrentThread.Priority = ThreadPriority.Highest;

            int from = 100000;// Convert.ToInt32(txtFrom.Text);
            int to = 999999;//Convert.ToInt32(txtTo.Text);
            int numbers = 2000; //Convert.ToInt32(txtNumbers.Text);
            int range = 50;// Convert.ToInt32(txtRange.Text);

            var generatedFrequencies = new List<Frequency>(to - from);
            var availableRanges = new List<AvailableRange>(to - from + 1);

            //AvailableRange maxAvailableRange = new AvailableRange();

            var random = new Random();

            DateTime first = DateTime.Now;

            for (int i = 0; i < numbers; i++)
            {
                var frequency = new Frequency();

                if (availableRanges.Count == 0)
                {
                    frequency.Number = random.Next(from, to);
                    frequency.Number = (int)Math.Round((decimal)frequency.Number / 5) * 5;
                    int fromValue = frequency.Number - (range / 2);
                    int toValue = frequency.Number + (range / 2);

                    frequency.From = fromValue < from ? from : fromValue;
                    frequency.To = toValue > to ? to : toValue;

                    generatedFrequencies.Add(frequency);

                    var availableRange1 = new AvailableRange { From = @from, To = frequency.From };
                    availableRange1.RangeLong = availableRange1.To - availableRange1.From;
                    availableRanges.Add(availableRange1);

                    var availableRange2 = new AvailableRange { From = frequency.To, To = to };
                    availableRange2.RangeLong = availableRange2.To - availableRange2.From;
                    availableRanges.Add(availableRange2);
                }
                else
                {
                    DateTime d1 = DateTime.Now;
                    int max = 0, index = 0;

                    for (int j = 0; j < availableRanges.Count; j++)
                    {
                        if (availableRanges[j].RangeLong > range)
                        {
                            index = j;
                        }


                    }

                    DateTime d2 = DateTime.Now;
                    double total1 = (d2 - d1).TotalMilliseconds;

                    AvailableRange availableRange = availableRanges[index];

                    if (availableRange.RangeLong <= range)
                    {
                        Console.WriteLine("there is no available pathes " + generatedFrequencies.Count);

                        break;
                    }

                    DateTime d3 = DateTime.Now;
                    double total2 = (d3 - d2).TotalMilliseconds;

                    frequency.Number = random.Next(availableRange.From + (range / 2), availableRange.To - (range / 2));
                    frequency.Number = (int)Math.Round((decimal)frequency.Number / 5) * 5;
                    int fromValue = frequency.Number - (range / 2);
                    int toValue = frequency.Number + (range / 2);

                    frequency.From = fromValue < from ? from : fromValue;
                    frequency.To = toValue > to ? to : toValue;
                    generatedFrequencies.Add(frequency);

                    var availableRange1 = new AvailableRange { From = availableRange.From, To = frequency.From, RangeLong = frequency.From - availableRange.From };
                    availableRanges.Add(availableRange1);

                    //availableRange.From = 1;


                    var availableRange2 = new AvailableRange { From = frequency.To, To = availableRange.To, RangeLong = availableRange.To - frequency.To };
                    availableRanges.Add(availableRange2);

                    //availableRange.To = frequency.From;
                    //availableRange.RangeLong = availableRange.To - availableRange.From;


                    DateTime d4 = DateTime.Now;
                    double total3 = (d4 - d3).TotalMilliseconds;

                    //availableRange.RangeLong = 0;
                    availableRanges.RemoveAt(index);

                    DateTime d5 = DateTime.Now;
                    double total4 = (d5 - d4).TotalMilliseconds;

                    double total = (d5 - d1).TotalMilliseconds;
                    if (total > 1)
                    {
                       // Console.WriteLine(total + @"     :     " + total1 + @"     :     " + total2 + @"     :     " + total3 + @"     :     " + total4 +
                       //   @"    frequency     :     " + frequency.Number + @"  max    :     " + max + @"  index   :     " + index);
                    }
                }

            }
            DateTime last = DateTime.Now;
            Console.WriteLine((last - first));

            Console.ReadLine();
        }
    }


    public class Frequency
    {
        public int From { get; set; }
        public int To { get; set; }
        public int Number { get; set; }
        public override string ToString()
        {
            return " from  :  " + From + " to  :  " + To + " number  :  " + Number;
        }
    }

    public class AvailableRange
    {
        public int From { get; set; }
        public int To { get; set; }
        public int RangeLong { get; set; }

        public override string ToString()
        {
            return " from  :  " + From + " to  :  " + To + " RangeLong  :  " + RangeLong;
        }
    }
}

现在的问题是这段代码需要一些时间 当我分析代码时,我预计某些周期需要 15 毫秒,而其他周期需要 0 毫秒 如果循环数很少,则不会出现此问题 我试图解决这个问题,但我找不到答案 有什么问题

【问题讨论】:

  • 我建议你使用Math.Round(... MidpointRounding.AwayFromZero)。它通常更容易理解,因为它是他们在学校教的四舍五入(0.5 舍入)
  • 谢谢,但真正的问题听不见,如果你设置从 1000000 到 9999999 和数字 20000,问题就会出现
  • 我按照你说的做了,但问题仍然存在

标签: c# .net performance


【解决方案1】:

不使用DateTime 来衡量性能。使用System.Diagnostics.Stopwatch

【讨论】:

    【解决方案2】:

    您看到的是 System.DateTime 结构的 16 毫秒精度限制。

    见http://blogs.msdn.com/b/ericlippert/archive/2010/04/08/precision-and-accuracy-of-datetime.aspx。

    您需要使用System.Diagnostics.Stopwatch 类代替任何类型的性能评估,因为它通常精确到微秒(取决于测试时发生的线程上下文切换量)。

    【讨论】:

      【解决方案3】:

      我认为您无法获得准确的测量结果,因为这是在多任务环境中运行的用户模式代码。即使线程优先级设置为最高,它也可以被任何内核模式进程取代。

      【讨论】:

      • 问题是为什么有些周期需要 0 毫秒,而另一些需要 15 毫秒,结果不合理
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-02-02
      • 2014-12-09
      • 1970-01-01
      • 2011-07-30
      • 1970-01-01
      • 1970-01-01
      • 2015-08-28
      相关资源
      最近更新 更多