Помогите понять оптимизацию C #

Я играл с C # и хотел ускорить программу. Я внес изменения и смог это сделать. Однако мне нужна помощь в понимании того, почему это изменение ускорилось.

Я попытался сократить код до более удобного для понимания вопроса. Score1 и Report1 - более медленный способ. Score2 и Report2 - более быстрый способ. Первый метод сначала сохраняет строку и int в структуре параллельно. Затем в последовательном цикле он перебирает массив этих структур и записывает их данные в буфер. Второй метод сначала записывает данные в строковый буфер параллельно. Затем в последовательном цикле он записывает строковые данные в буфер. Вот несколько примеров времени выполнения:

Общее среднее время выполнения 1 = 0,492087 с. Я попытался сократить код до ...

Я играл с C # и хотел ускорить программу. Я внес изменения и смог это сделать. Однако мне нужна помощь в понимании того, почему это изменение ускорилось.

Я попытался сократить код до более удобного для понимания вопроса. Score1 и Report1 - более медленный способ. Score2 и Report2 - более быстрый способ. Первый метод сначала сохраняет строку и int в структуре параллельно. Затем в последовательном цикле он перебирает массив этих структур и записывает их данные в буфер. Второй метод сначала записывает данные в строковый буфер параллельно. Затем в последовательном цикле он записывает строковые данные в буфер. Вот несколько примеров времени выполнения:

Общее среднее время выполнения 1 = 0,492087 с. Я попытался сократить код до ...

Я играл с C # и хотел ускорить программу. Я внес изменения и смог это сделать. Однако мне нужна помощь в понимании того, почему это изменение ускорилось.

Я попытался сократить код до более удобного для понимания вопроса. Score1 и Report1 - более медленный способ. Score2 и Report2 - более быстрый способ. Первый метод сначала сохраняет строку и int в структуре параллельно. Затем в последовательном цикле он перебирает массив этих структур и записывает их данные в буфер. Второй метод сначала записывает данные в строковый буфер параллельно. Затем в последовательном цикле он записывает строковые данные в буфер. Вот несколько примеров времени выполнения:

Общее среднее время выполнения 1 = 0,492087 с. Я внес изменения и смог это сделать. Однако мне нужна помощь в понимании того, почему это изменение ускорилось.

Я попытался сократить код до более удобного для понимания вопроса. Score1 и Report1 - более медленный способ. Score2 и Report2 - более быстрый способ. Первый метод сначала сохраняет строку и int в структуре параллельно. Затем в последовательном цикле он перебирает массив этих структур и записывает их данные в буфер. Второй метод сначала записывает данные в строковый буфер параллельно. Затем в последовательном цикле он записывает строковые данные в буфер. Вот несколько примеров времени выполнения:

Общее среднее время выполнения 1 = 0,492087 с. Я внес изменения и смог это сделать. Однако мне нужна помощь в понимании того, почему это изменение ускорилось.

Я попытался сократить код до более удобного для понимания вопроса. Score1 и Report1 - более медленный способ. Score2 и Report2 - более быстрый способ. Первый метод сначала сохраняет строку и int в структуре параллельно. Затем в последовательном цикле он перебирает массив этих структур и записывает их данные в буфер. Второй метод сначала записывает данные в строковый буфер параллельно. Затем в последовательном цикле он записывает строковые данные в буфер. Вот несколько примеров времени выполнения:

Общее среднее время выполнения 1 = 0,492087 с. Score1 и Report1 - более медленный способ. Score2 и Report2 - более быстрый способ. Первый метод сначала сохраняет строку и int в структуре параллельно. Затем в последовательном цикле он перебирает массив этих структур и записывает их данные в буфер. Второй метод сначала записывает данные в строковый буфер параллельно. Затем в последовательном цикле он записывает строковые данные в буфер. Вот несколько примеров времени выполнения:

Общее среднее время выполнения 1 = 0,492087 с. Score1 и Report1 - более медленный способ. Score2 и Report2 - более быстрый способ. Первый метод сначала сохраняет строку и int в структуре параллельно. Затем в последовательном цикле он перебирает массив этих структур и записывает их данные в буфер. Второй метод сначала записывает данные в строковый буфер параллельно. Затем в последовательном цикле он записывает строковые данные в буфер. Вот несколько примеров времени выполнения:

Общее среднее время выполнения 1 = 0,492087 с. Общее среднее время прогона 2 = 0,273619 сек

Когда я работал с более ранней непараллельной версией этого, время было почти таким же. В чем разница с параллельной версией?

Даже если я уменьшу цикл в Report1, чтобы записать одну строку вывода в буфер, он все равно будет медленнее (общее время около 0,42 секунды).

Вот упрощенный код :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Threading.Tasks;
using System.IO;

namespace OptimizationQuestion
{
    class Program
    {
        struct ValidWord
        { 
            public string word;
            public int score;
        }
        ValidWord[] valid;
        StringBuilder output;
        int total; 

        public void Score1(string[] words)
        {
            valid = new ValidWord[words.Length];

            for (int i = 0; i < words.Length; i++)
            {
                StringBuilder builder = new StringBuilder();

                foreach (char c in words[i])
                {
                    if (c != 'U')
                        builder.Append(c);
                }
                if (words[i].Length == 3)
                {
                    valid[i] = new ValidWord 
                    { word = builder.ToString(), score = words[i].Length };
                }
            }
        }
        public void Report1(StringBuilder outputBuffer)
        {
            int total = 0;
            foreach (ValidWord wordInfo in valid)
            {
                if (wordInfo.score > 0)
                {
                    outputBuffer.AppendLine(String.Format("{0} {1}", wordInfo.word.ToString(), wordInfo.score));
                    total += wordInfo.score;
                }
            }
            outputBuffer.AppendLine(string.Format("Total = {0}", total));
        }

        public void Score2(string[] words)
        {
            output = new StringBuilder();
            total = 0;           
            for (int i = 0; i < words.Length; i++)
            {
                StringBuilder builder = new StringBuilder();

                foreach (char c in words[i])
                {
                    if (c != 'U')
                        builder.Append(c);
                }
                if (words[i].Length == 3)
                {
                    output.AppendLine(String.Format("{0} {1}", builder.ToString(), words[i].Length));
                    total += words[i].Length;
                }
            }
        }
        public void Report2(StringBuilder outputBuffer)
        {
            outputBuffer.Append(output.ToString());
            outputBuffer.AppendLine(string.Format("Total = {0}", total));
        } 
        static void Main(string[] args)
        {
            Program[] program = new Program[100];
            for (int i = 0; i < program.Length; i++)
                program[i] = new Program(); 

            string[] words = File.ReadAllLines("words.txt");

            Stopwatch stopwatch = new Stopwatch();
            const int TIMING_REPETITIONS = 20;
            double averageTime1 = 0.0;
            StringBuilder output = new StringBuilder();
            for (int i = 0; i < TIMING_REPETITIONS; ++i)
            {
                stopwatch.Reset();
                stopwatch.Start();
                output.Clear();
                Parallel.ForEach<Program>(program, p =>
                    {
                        p.Score1(words);
                    });
                for (int k = 0; k < program.Length; k++)
                    program[k].Report1(output);
                stopwatch.Stop();
                averageTime1 += stopwatch.Elapsed.TotalSeconds;
                GC.Collect();
            }
            averageTime1 /= (double)TIMING_REPETITIONS;
            Console.WriteLine(string.Format("Run 1 Total Average Time = {0:0.000000} sec", averageTime1));
            double averageTime2 = 0.0;
            for (int i = 0; i < TIMING_REPETITIONS; ++i)
            {
                stopwatch.Reset();
                stopwatch.Start();
                output.Clear();
                Parallel.ForEach<Program>(program, p =>
                    {
                        p.Score2(words);
                    });
                for (int k = 0; k < program.Length; k++)
                    program[k].Report2(output);
                stopwatch.Stop();
                averageTime2 += stopwatch.Elapsed.TotalSeconds;
                GC.Collect();
            }
            averageTime2 /= (double)TIMING_REPETITIONS;
            Console.WriteLine(string.Format("Run 2 Total Average Time = {0:0.000000} sec", averageTime2));
            Console.ReadLine();
        }
    }
}
12
задан jlim 9 February 2011 в 06:10
поделиться