2

txtファイル(csvまたはタブ区切り)を読み込んで、各行をVector3に変換し、それを配列に追加してさらに処理しようとしています

私のコードはこれまでのところ機能していますが、ファイルを読み込むのに時間がかかります。読み込まれる各ファイルは 6 mb から 25 mb の間です

foreachコードは実行され、期待どおりに動作しますが、このステートメントのどこかでボトルネックになっているようです? より迅速な方法はありますか、それとも期待する必要があるものですか?

String[] pntsText = File.ReadAllLines(args[0]);
List<Vector3> pnts = new List<Vector3>();
Console.WriteLine("Start Building Points Array ...");
int noOfPnts = pntsText.Length;
int currentPntNo=0;
Console.CursorVisible = false;

foreach (string pntText in pntsText)
{
    currentPntNo++;
    Console.Clear();
    Console.Write(noOfPnts - currentPntNo + " left to process");
    string[] splitXYZ = pntText.Split(new string[] { args[1] }, StringSplitOptions.None);
    Vector3 ve2 = new Vector3(float.Parse(splitXYZ[0]), float.Parse(splitXYZ[1]), float.Parse(splitXYZ[2]));
    pnts.Add(ve2);
}

Console.WriteLine("Points Array Complete");
4

3 に答える 3

3

問題はコンソールの通知にあると思います。コメントアウトして、パフォーマンスが向上するかどうかをテストできます。ストップウォッチを使用してプログラムの実行時間を計ることをお勧めします。

次の LINQ クエリを試して、のリストを取得することもできますVector3

List<Vector3> list

 = pntsText.Select(r => new { Splitted = r.Split(new string[] { "," }, StringSplitOptions.None) })
           .Select(t => new Vector3(float.Parse(t.Splitted[0]), float.Parse(t.Splitted[1]), float.Parse(t.Splitted[2])))
           .ToList();

しかし、これは内部的にループを行うため、それによってパフォーマンスが向上するかどうかはわかりません。また、処理中にコンソールに出力が得られません。

于 2013-01-30T06:29:40.057 に答える
1

ファイル全体を 1 つの文字列に読み取り、 を呼び出しstr.Split(new[] {',', '\n'})て、すべてのベクター パーツの 1 つの配列を取得します。次にループスルーし、それらを 3 秒で解析します。これにより、 への複数回の呼び出しが防止されSplitます。また、反復ごとにコンソールを更新することも避けてください。たぶん100回ごと?

于 2013-02-13T20:05:34.060 に答える
1

ポイントを分割するために Split メソッドを使用しています。

string[] splitXYZ = pntText.Split(new string[] 
  { args[1] }, StringSplitOptions.None);

これを for ループに入れると、返された配列オブジェクトと各配列要素に String オブジェクトにメモリが割り当てられるため、実際にはパフォーマンスが向上しません。IndexOf を Substring と組み合わせて使用​​することを検討してください。これをテストする必要がある速度がどれほど速いかわかりません。

この問題に関するドキュメントを読む:

パフォーマンスに関する考慮事項

Split メソッドは、返された配列オブジェクトにメモリを割り当て、配列要素ごとに String オブジェクトを割り当てます。アプリケーションで最適なパフォーマンスが必要な場合、またはアプリケーションでメモリ割り当ての管理が重要な場合は、IndexOf メソッドまたは IndexOfAny メソッド、および必要に応じて Compare メソッドを使用して、文字列内の部分文字列を検索することを検討してください。

文字列を区切り文字で分割する場合は、IndexOf または IndexOfAny メソッドを使用して、文字列内の区切り文字を見つけます。文字列を区切り文字列で分割する場合は、IndexOf または IndexOfAny メソッドを使用して、区切り文字列の最初の文字を見つけます。次に、Compare メソッドを使用して、最初の文字の後の文字が区切り文字列の残りの文字と等しいかどうかを判断します。

もう 1 つのポイントは、3 回の解析部分を含む、返されたポイント配列ごとにオブジェクト (ベクター) を作成していることです。これにより、パフォーマンスもいくらか犠牲になります。

Vector3 ve2 = new Vector3(float.Parse(splitXYZ[0]), 
   float.Parse(splitXYZ[1]), float.Parse(splitXYZ[2]));

この時点でこれが本当に必要ない場合 (必要に応じて)、情報をテキストまたは構造体の形式で保持し、後で処理する必要があるときに Vector オブジェクトを作成できます。

お役に立てれば

于 2013-01-30T06:45:29.827 に答える