0

ファイルのバイトを読み取ってから8つの個別の文字列を作成する次のコードがあります。完了すると、8つの文字列が結合されますが、500MBのファイルを読み取ると、このコードは10時間以上かかるため、実行をあきらめます.

このコードの効率を上げて、より高速に実行できるようにする方法はありますか?

namespace ConsoleApplication1
{
    public class object1
    {
        public static Byte[] split1 = new Byte[18082460];
        public static Byte[] split2 = new Byte[18082460];
        public static Byte[] split3 = new Byte[18082460];
        public static Byte[] split4 = new Byte[18082460];
        public static Byte[] split5 = new Byte[18082460];
        public static Byte[] split6 = new Byte[18082460];
        public static Byte[] split7 = new Byte[18082460];
        public static Byte[] split8 = new Byte[18082452];

        public static String[] output = new String[8];

        public void run1()
        {
            for (int i = 0; i < split1.Length; i++)
            {
                output[0] += "0x" + split1[i] + ", ";
                Program.amountDone[0] += 1;
                Thread.Sleep(1);
            }
        }
        public void run2()
        {
            for (int i = 0; i < split2.Length; i++)
            {
                output[1] += "0x" + split2[i] + ", ";
                Program.amountDone[1] += 1;
                Thread.Sleep(1);
            }
        }
        public void run3()
        {
            for (int i = 0; i < split3.Length; i++)
            {
                output[2] += "0x" + split3[i] + ", ";
                Program.amountDone[2] += 1;
                Thread.Sleep(1);
            }
        }
        public void run4()
        {
            for (int i = 0; i < split4.Length; i++)
            {
                output[3] += "0x" + split4[i] + ", ";
                Program.amountDone[3] += 1;
                Thread.Sleep(1);
            }
        }
        public void run5()
        {
            for (int i = 0; i < split5.Length; i++)
            {
                output[4] += "0x" + split5[i] + ", ";
                Program.amountDone[4] += 1;
                Thread.Sleep(1);
            }
        }
        public void run6()
        {
            for (int i = 0; i < split6.Length; i++)
            {
                output[5] += "0x" + split6[i] + ", ";
                Program.amountDone[5] += 1;
                Thread.Sleep(1);
            }
        }
        public void run7()
        {
            for (int i = 0; i < split7.Length; i++)
            {
                output[6] += "0x" + split7[i] + ", ";
                Program.amountDone[6] += 1;
                Thread.Sleep(1);
            }
        }
        public void run8()
        {
            for (int i = 0; i < split8.Length; i++)
            {
                if (i == split8.Length)
                {
                    output[7] += "0x" + split8[i];
                }
                else
                {
                    output[7] += "0x" + split8[i] + ", ";
                }
                Program.amountDone[7] += 1;
                Thread.Sleep(1);
            }
        }
    };
    class Program
    {
        public static int curPoint = 0;
        public static object1 obj = new object1();
        public static Thread thread1 = new Thread(new ThreadStart(obj.run1));
        public static Thread thread2 = new Thread(new ThreadStart(obj.run2));
        public static Thread thread3 = new Thread(new ThreadStart(obj.run3));
        public static Thread thread4 = new Thread(new ThreadStart(obj.run4));
        public static Thread thread5 = new Thread(new ThreadStart(obj.run5));
        public static Thread thread6 = new Thread(new ThreadStart(obj.run6));
        public static Thread thread7 = new Thread(new ThreadStart(obj.run7));
        public static Thread thread8 = new Thread(new ThreadStart(obj.run8));
        public static int[] amountDone = { 0, 0, 0, 0, 0, 0, 0, 0 };

        [STAThread]
        static void Main(string[] args)
        {
            Byte[] bytes = GetBytesFromFile(@"C:\Users\JLT\Desktop\320kbTest.rar");

            Array.Copy(bytes, 0, object1.split1, 0, 18082460);
            Array.Copy(bytes, 18082461, object1.split2, 0, 18082460);
            Array.Copy(bytes, 36164922, object1.split3, 0, 18082460);
            Array.Copy(bytes, 54247383, object1.split4, 0, 18082460);
            Array.Copy(bytes, 72329844, object1.split5, 0, 18082460);
            Array.Copy(bytes, 90412305, object1.split6, 0, 18082460);
            Array.Copy(bytes, 108494766, object1.split7, 0, 18082460);
            Array.Copy(bytes, 126577227, object1.split8, 0, 18082452);

            thread1.Start();
            thread2.Start();
            thread3.Start();
            thread4.Start();
            thread5.Start();
            thread6.Start();
            thread7.Start();
            thread8.Start();


            String output = "Byte[] rawData = { ";

            while (true)
            {
                if (thread1.IsAlive || thread2.IsAlive || thread3.IsAlive || thread4.IsAlive || thread5.IsAlive || thread6.IsAlive || thread7.IsAlive || thread8.IsAlive)
                {
                    int temp = 0;
                    foreach (int inter in amountDone)
                    {
                        temp += inter;
                    }
                    Console.WriteLine(temp + " | " + bytes.Length);
                    Thread.Sleep(100);
                    Console.Clear();
                }
                else
                {
                    int temp = 0;
                    foreach (int inter in amountDone)
                    {
                        temp += inter;
                    }
                    if (temp < bytes.Length - 1)
                    {
                        Thread.Sleep(100);
                    }
                    else
                    {
                        break;
                    }
                }
            }

            output += object1.output[0];
            output += object1.output[1];
            output += object1.output[2];
            output += object1.output[3];
            output += object1.output[4];
            output += object1.output[5];
            output += object1.output[6];
            output += object1.output[7];

            output += "};";
            Console.WriteLine(output);
        }

        public static byte[] GetBytesFromFile(string fullFilePath)
        {
            FileStream fs = File.OpenRead(fullFilePath);
            try
            {
                byte[] bytes = new byte[fs.Length];
                fs.Read(bytes, 0, Convert.ToInt32(fs.Length));
                fs.Close();
                return bytes;
            }
            finally
            {
                fs.Close();
            }

        }
    }
}
4

2 に答える 2

7

このコードの効率を上げて、より高速に実行できるようにする方法はありますか?

さて、私は2つの差し迫った問題を見ることができます:

  • あなたはあなたのループで寝ています。なんで?
  • 文字列連結を何度も使用しています。長い文字列を作成するとき、それはひどいものになるでしょう。

個人的には、最初からスレッドを完全に取り除くことをお勧めします。これによりコードがはるかに複雑になり、上記の 2 つの問題を修正すれば、単一のスレッドで問題なくなると思います。

コンソールに出力を書き込んでいるだけなので、最も簡単な方法は、ファイル全体をメモリにまったく読み込まないようにすることです。一度に 1 ブロック (たとえば 32K) を読み取り、各バイトを反復処理して、各バイトの 16 進値をコンソール (バッファリングされると予想されます...) に直接書き込みます。

メモリ内に文字列を構築する必要がある場合は、a を使用します (詳細な説明については、このトピックに関する私の記事をStringBuilder参照してください) 。ただし、そうする必要はまったくないと思います。

于 2012-12-27T11:48:34.977 に答える
3

プログラムは、1 バイトを処理してから 1 ミリ秒スリープ状態になる 8 つのスレッドで 144 MB のデータを処理します。

したがって、プログラムは少なくとも 5 時間は睡眠に費やすことになります...

を削除してThread.Sleep、プログラムの効率が向上するかどうかを試してみることをお勧めします。

于 2012-12-27T11:53:11.940 に答える