3

私のプログラムでは、大きなテキストファイル(〜300 mb)を書き込む必要があります。テキストファイルには、スペースで区切られた数字が含まれています。このコードを使用しています。

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

4 に答える 4

4

効率を向上させる1つの方法は、出力ストリームのバッファーを大きくすることです。デフォルトを使用しているため、おそらく1kのバッファーが提供されますが、64k未満のバッファーでは最大のパフォーマンスは得られません。次のようにファイルを開きます。

new StreamWriter("guesses.txt", new UTF8Encoding(false, true), 65536)
于 2011-04-19T15:46:22.670 に答える
2

行ごとに読み書きする(ReadLineとWriteLine)のではなく、データの大きなブロック(ReadBlockとWrite)を読み書きする必要があります。このようにして、ディスクへのアクセスが大幅に減り、パフォーマンスが大幅に向上します。ただし、各行の終わりを管理する必要があります(Environment.NewLineを参照してください)。

于 2011-04-19T15:42:20.233 に答える
1

BinaryWriterを使用すると、効率を向上させることができます。次に、整数を直接書き出すことができます。これにより、読み取り時の解析ステップと書き込み時のToString変換をスキップできます。

また、そこにたくさんのスレッドを作成しているように見えます。スレッドを追加すると、パフォーマンスが低下します。スレッドは非常に重いオブジェクトであるため、すべての作業を1つのスレッドで実行する必要があります。

これは、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++;
        }
    }
于 2011-04-19T15:34:11.683 に答える
1

間にバッファを使用してみてください。BGufferdSTreamがあります。現在、非常に非効率的なディスクアクセスパターンを使用しています。

于 2011-04-19T15:37:07.020 に答える