1

この質問は最初の 2 部の続きです。私がどこから来たのか知りたい人は誰でも 1 部と 2 部を参照できますが、必須ではありません。

大量のトラフィック用に最適化する必要がある書き込みファイル

大量のトラフィックに最適化する必要がある書き込みファイル パート 2

これで作業スニペットができました。関連する部分は以下のとおりです。

    public static class memoryStreamClass
    {
        static MemoryStream ms1 = new MemoryStream();

        public static void fillBuffer(string outputString)
        {
            byte[] outputByte = Encoding.ASCII.GetBytes(outputString);

            ms1.Write(outputByte, 0, outputByte.Length);

            if (ms1.Length > 8100)
            {
                emptyBuffer(ms1);
                ms1.SetLength(0);
                ms1.Position = 0;
            }
        }

        static void emptyBuffer(MemoryStream ms)
        {
            FileStream outStream = new FileStream("c:\\output.txt", FileMode.Append);

            ms.WriteTo(outStream);
            outStream.Flush();
            outStream.Close();
        }

上記のスニペットは問題なく動作し、バグもありません。書き込みごとに約 8KB のデータを出力します。

上記のコードをマルチスレッド化して、IO 書き込みのボトルネックのパフォーマンスを向上させようとすると、問題が発生します。以下のスニペットは、私が試みたものです。

基本的に、私は2つの同一のmemoryStreamを持っています。たとえば、ms1がいっぱいの場合、ms1をファイルに書き込み、ms1が書き込み中にms2に切り替えます。逆もまた同様です。

    public static class memoryStreamClass
    {
        static MemoryStream ms1 = new MemoryStream();
        static MemoryStream ms2 = new MemoryStream();
        static int c = 1;

        public static void fillBuffer(string outputString)
        {
            byte[] outputByte = Encoding.ASCII.GetBytes(outputString);

            if (c == 1)
            {
                ms1.Write(outputByte, 0, outputByte.Length);

                if (ms1.Length > 8100)
                {
                    c = 2;

                    Thread thread1 = new Thread( () => emptyBuffer(ms1));
                    thread1.Start();

                    ms1.SetLength(0);
                    ms1.Position = 0;
                }
            }
            else
            {
                ms2.Write(outputByte, 0, outputByte.Length);

                if (ms2.Length > 8100)
                {
                    c = 1;

                    Thread thread2 = new Thread(() => emptyBuffer(ms2));
                    thread2.Start();

                    ms2.SetLength(0);
                    ms2.Position = 0;

                }
            }
        }

上記のコードはコンパイルして実行できますが、出力書き込みは常に 8KB とは限らず、(私のシングル スレッド プログラムよりも) 頻繁に書き込みます。誰かが私を啓発し、私のプログラムの何が問題なのかを指摘できますか? どうもありがとうございます

4

1 に答える 1

1

あなたのコードはひどく壊れており、パフォーマンスを向上させるために 2 つのバッファーを使用するというあなたの考えは、ほぼ間違いなく過剰な最適化です。ただし、このコード ブロックには明らかな問題が 1 つあります。

Thread thread1 = new Thread( () => emptyBuffer(ms1));
thread1.Start();

ms1.SetLength(0);
ms1.Position = 0;

このコードの機能は次のとおりです。

  • スレッドを開始してバッファを処理する
  • すぐにそのバッファをクリアします

問題は、スレッドが開始される前に「クリアな」コードがほぼ確実に実行されることです (一般的に言えば、実行中のメソッドはスレッド コンテキストが変更される前に完了するため)。したがって、 を呼び出すemptyBufferまでに、MemoryStreamはすでに空になっています。

あなたの統計は悪い考えです。非静的インスタンスをemptyBufferメソッドに渡してから を設定ms1 = new MemoryStream()すると、おそらくより適切に機能するコードになります。しかし、最終的には、このコードには概念上の欠陥があり、再設計を検討する必要があります。

于 2012-07-17T16:58:42.310 に答える