4

小さなアプリケーションをより速く動作させるのに苦労しています。私は開発者ではないので、これをそのまま機能させるのに時間がかかりました。10m の入力ファイルを処理するのに約 1 時間かかります。

コードを以下に示します。入力ファイルの例を次に示します。

4401、imei:0000000000、2012-09-01 12:12:12.9999

using System;
using System.Globalization;
using System.IO;

class Sample 
{
    public static void Main(string[] args) 
    {
if (args.Length == 0)
                {
                    return;
                }


                using (FileStream stream = File.Open(args[0], FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                {

                    using (StreamReader streamReader = new StreamReader(stream))
                    {
                        System.Text.StringBuilder builder = new System.Text.StringBuilder();
                        while (!streamReader.EndOfStream)
                        {
                            var line = streamReader.ReadLine();
                            var values = line.Split(',');
                            DateTime dt = new DateTime();
                            DateTime.TryParse(values[2], out dt);
                            values[2] = Convert.ToString(dt.Ticks);

                            string[] output = new string[values.Length];
                            bool firstColumn = true;
                            for (int index = 0; index < values.Length; index++)
                            {
                                if (!firstColumn)
                                    builder.Append(',');
                                builder.Append(values[index]);
                                firstColumn = false;

                            }
                            File.WriteAllText(args[1], builder.AppendLine().ToString());

                        }
                    }
                }
            }
}
4

2 に答える 2

6

最大のパフォーマンス ヒットは、行が読み取られるたびに、(これまでに処理された) ファイル全体がディスクに書き戻されることです。簡単に勝つには、StringBuilder をループの外に移動してみてください。

            System.Text.StringBuilder builder = new System.Text.StringBuilder();

            using (FileStream stream = File.Open(args[0], FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                using (StreamReader streamReader = new StreamReader(stream))
                {
                    while (!streamReader.EndOfStream)
                    {
                        var line = streamReader.ReadLine();
                        var values = line.Split(',');
                        DateTime dt = new DateTime();
                        DateTime.TryParse(values[2], out dt);
                        values[2] = Convert.ToString(dt.Ticks);

                        string[] output = new string[values.Length];
                        bool firstColumn = true;
                        for (int index = 0; index < values.Length; index++)
                        {
                            if (!firstColumn)
                                builder.Append(',');
                            builder.Append(values[index]);
                            firstColumn = false;
                        }
                        builder.AppendLine();
                    }
                }
            }

            File.WriteAllText(args[1], builder.ToString());

さらにリファクタリングする場合は、コンマ区切りロジックを変更します。

            System.Text.StringBuilder builder = new System.Text.StringBuilder();

            using (FileStream stream = File.Open(args[0], FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                using (StreamReader streamReader = new StreamReader(stream))
                {
                    while (!streamReader.EndOfStream)
                    {
                        var line = streamReader.ReadLine();
                        var values = line.Split(',');
                        DateTime dt = new DateTime();
                        DateTime.TryParse(values[2], out dt);
                        values[2] = Convert.ToString(dt.Ticks);

                        builder.AppendLine(string.Join(",", values));
                    }
                }
            }

            File.WriteAllText(args[1], builder.ToString());

編集:メモリの使用を避けるには、を削除し、Stringbuilder別のものを使用FileStreamしてディスクに書き込みます。提案されたソリューション(を使用List)は、依然としてかなりの量のメモリを使用し、より大きなファイルで壊れる可能性があります。

        using (FileStream input = File.Open(args[0], FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
        using (FileStream output = File.Create(args[1]))
        {
            using (StreamReader streamReader = new StreamReader(input))
            using (StreamWriter streamWriter = new StreamWriter(output))
            {
                while (!streamReader.EndOfStream)
                {
                    var line = streamReader.ReadLine();
                    var values = line.Split(',');
                    DateTime dt = new DateTime();
                    DateTime.TryParse(values[2], out dt);
                    values[2] = Convert.ToString(dt.Ticks);

                    streamWriter.WriteLine(string.Join(",", values));
                }
            }
        }
于 2012-10-11T01:33:36.260 に答える
0

これが私が見つけたもので、これを修正して大きなファイルを処理できます。

@Muzz と @Vache の支援に感謝します。

string line = ""; 
System.IO.StreamReader file = new System.IO.StreamReader("c:/test.txt"); 
List<string> convertedLines = new List<string>(); 
while ((line = file.ReadLine()) != null) 
{
    string[] lineSplit = line.Split(','); 
    DateTime dt = new DateTime(); 
    DateTime.TryParse(lineSplit[2], out dt); 
    lineSplit[2] = Convert.ToString(dt.Ticks); 
 
    string convertedline = lineSplit[0] + "," + lineSplit[1] + "," + lineSplit[2]; 
    convertedLines.Add(convertedline);
}
file.Close();
File.WriteAllLines("c:/newTest.txt", convertedLines);
于 2012-10-11T15:20:40.103 に答える