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

您正在使用拆分方法来拆分您的点:

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

在 for 循环中使用 this 并不是很高效,因为它为返回的数组对象分配内存,并为每个数组元素分配一个 String 对象。考虑将 IndexOf 与 Substring 结合使用,我不确定您必须测试它有多快。

阅读有关此问题的文档:

性能注意事项

Split 方法为返回的数组对象分配内存,并为每个数组元素分配一个 String 对象。如果您的应用程序需要最佳性能,或者如果管理内存分配在您的应用程序中至关重要,请考虑使用 IndexOf 或 IndexOfAny 方法以及可选的 Compare 方法来定位字符串中的子字符串。

如果要在分隔符处拆分字符串,请使用 IndexOf 或 IndexOfAny 方法来定位字符串中的分隔符。如果要在分隔符字符串处拆分字符串,请使用 IndexOf 或 IndexOfAny 方法来定位分隔符字符串的第一个字符。然后使用比较方法来确定第一个字符之后的字符是否等于分隔符字符串的其余字符。

另一点是您正在为每个返回的点数组创建一个对象(向量),包括 3 倍的 Parse 部分,这也需要一些性能:

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

如果此时真的不需要这样做(取决于您的需要),您可以将信息以文本甚至结构的形式保存,并在以后需要处理它时创建 Vector 对象。

希望这可以帮助

于 2013-01-30T06:45:29.827 回答
1

将整个文件读入一个字符串并调用str.Split(new[] {',', '\n'})以获取所有矢量部分的单个数组。然后循环,在 3s 内解析它们。这将防止多次调用Split. 还要避免在每次迭代时更新控制台。也许每100个?

于 2013-02-13T20:05:34.060 回答