Повышение производительности streamwriter в c # - PullRequest
3 голосов
/ 19 апреля 2011

в моей программе мне нужно написать большие текстовые файлы (~ 300 МБ), текстовые файлы содержат числа, разделенные пробелами, я использую этот код:

TextWriter guessesWriter = TextWriter.Synchronized(new StreamWriter("guesses.txt"));

private void QueueStart()
    {
        while (true)
        {
            if (writeQueue.Count > 0)
            {
                guessesWriter.WriteLine(writeQueue[0]);
                writeQueue.Remove(writeQueue[0]);
            }
        }
    }

private static void Check()
    {
        TextReader tr = new StreamReader("data.txt");

        string guess = tr.ReadLine();
        b = 0;
        List<Thread> threads = new List<Thread>();
        while (guess != null) // Reading each row and analyze it
        {
            string[] guessNumbers = guess.Split(' ');
            List<int> numbers = new List<int>();
            foreach (string s in guessNumbers) // Converting each guess to a list of numbers
                numbers.Add(int.Parse(s));

            threads.Add(new Thread(GuessCheck));
            threads[b].Start(numbers);
            b++;

            guess = tr.ReadLine();
        }
    }

    private static void GuessCheck(object listNums)
    {
        List<int> numbers = (List<int>) listNums;

        if (!CloseNumbersCheck(numbers))
        {
            writeQueue.Add(numbers[0] + " " + numbers[1] + " " + numbers[2] + " " + numbers[3] + " " + numbers[4] + " " + numbers[5] + " " + numbers[6]);
        }
    }

    private static bool CloseNumbersCheck(List<int> numbers)
    {
        int divideResult = numbers[0]/10;
        for (int i = 1; i < 6; i++)
        {
            if (numbers[i]/10 != divideResult)
                return false;
        }
        return true;
    }

файл data.txt содержитданные в этом формате: (точки означают больше чисел, следуя той же логике)

1 2 3 4 5 6 1
1 2 3 4 5 6 2
1 2 3 4 5 6 3
.
.
.
1 2 3 4 5 6 8
1 2 3 4 5 7 1
.
.
.

Я знаю, что это не очень эффективно, и я искал несколько советов, как сделать это быстрее.если вы ночью знаете, как сохранить БОЛЬШОЕ количество чисел более эффективно, чем .txt, я был бы признателен.

Ответы [ 4 ]

2 голосов
/ 19 апреля 2011

Одним из способов повышения эффективности является увеличение буфера в выходном потоке.Вы используете значения по умолчанию, которые дают вам, вероятно, буфер 1 КБ, но вы не увидите максимальной производительности с буфером менее 64 КБ.Откройте ваш файл так:

new StreamWriter("guesses.txt", new UTF8Encoding(false, true), 65536)
1 голос
/ 19 апреля 2011

Попробуйте использовать буфер между. Есть BGufferdSTream. Прямо сейчас вы используете очень неэффективные схемы доступа к диску.

1 голос
/ 19 апреля 2011

Вместо чтения и записи построчно (ReadLine и WriteLine), вы должны читать и записывать большой блок данных (ReadBlock и Write).Таким образом, вы получите доступ к диску намного меньше и значительно увеличите производительность.Но вам нужно будет управлять концом каждой строки (смотрите Environment.NewLine).

1 голос
/ 19 апреля 2011

Эффективность может быть улучшена с помощью BinaryWriter. Тогда вы можете просто написать целые числа напрямую. Это позволит вам пропустить этап синтаксического анализа при чтении и преобразование ToString при записи.

Похоже, что вы создаете связку потоков. Дополнительные темы замедляют вашу производительность. Вы должны выполнить всю работу в одном потоке, поскольку потоки являются очень тяжелыми объектами.

Вот более или менее прямое преобразование вашего кода для использования BinaryWriter. (Это не решает проблему потока.)

    BinaryWriter guessesWriter = new BinaryWriter(new StreamWriter("guesses.dat"));
    private void QueueStart()
    {
        while (true)
        {             
            if (writeQueue.Count > 0)
            {
                lock (guessesWriter)
                {
                    guessesWriter.Write(writeQueue[0]);
                }
                writeQueue.Remove(writeQueue[0]);
            }
        }
    }
    private const int numbersPerThread = 6;
    private static void Check()
    {
        BinaryReader tr = new BinaryReader(new StreamReader("data.txt"));
        b = 0;
        List<Thread> threads = new List<Thread>();
        while (tr.BaseStream.Position < tr.BaseStream.Length)
        {
            List<int> numbers = new List<int>(numbersPerThread);
            for (int index = 0; index < numbersPerThread; index++)
            {
                numbers.Add(tr.ReadInt32());
            }
            threads.Add(new Thread(GuessCheck));
            threads[b].Start(numbers);
            b++;
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...