Мне нужно либо использовать запросы Linq, либо перебирать данные более 100 000 в приложении. Скорость будет иметь важное значение. Я написал тест и не получил ожидаемых результатов. По сути, я передаю одни и те же данные двум разным функциям в цикле 100 раз. Функции аналогичны, за исключением того, что в одном я использую несколько запросов Linq, а в другом я итерирую данные вручную для построения информации. Код выглядит так:
Версия Linq:
//Get max and min of each
double maxX = (from node in pointCloud
select node.Node.Value.X).Max();
double maxY = (from node in pointCloud
select node.Node.Value.Y).Max();
double maxZ = (from node in pointCloud
select node.Node.Value.Z).Max();
double minX = (from node in pointCloud
select node.Node.Value.X).Min();
double minY = (from node in pointCloud
select node.Node.Value.Y).Min();
double minZ = (from node in pointCloud
select node.Node.Value.Z).Min();
//Extract all the x, y and z values into arrays
double[] x = (from node in pointCloud
select node.Node.Value.X).ToArray();
double[] y = (from node in pointCloud
select node.Node.Value.Y).ToArray();
double[] z = (from node in pointCloud
select node.Node.Value.Z).ToArray();
VS:
Ручная версия:
//Get max and min of each
double maxX = double.MinValue;
double maxY = double.MinValue;
double maxZ = double.MinValue;
double minX = double.MaxValue;
double minY = double.MaxValue;
double minZ = double.MaxValue;
List<double> x = new List<double>();
List<double> y = new List<double>();
List<double> z = new List<double>();
foreach (NodeDistance<KDTreeNode<g.Point3d>> node in pointCloud)
{
maxX = msf.Max(maxX, node.Node.Value.X);
maxY = msf.Max(maxY, node.Node.Value.Y);
maxZ = msf.Max(maxZ, node.Node.Value.Z);
minX = msf.Min(minX, node.Node.Value.X);
minY = msf.Min(minY, node.Node.Value.Y);
minZ = msf.Min(minZ, node.Node.Value.Z);
x.Add(node.Node.Value.X);
y.Add(node.Node.Value.Y);
z.Add(node.Node.Value.Z);
}
Вот загадка. Когда запускается версия Linq, это занимает намного больше времени в первый раз. Я запускаю секундомер перед тем, как начать цикл, а затем записываю прошедшее время после каждого запуска функции. Вот первые 5 раз, когда запускается функция Linq:
00:00:00.0425169 (after 1st run)
00:00:00.0433850
00:00:00.0437312
00:00:00.0440666
00:00:00.0443969
....
00:00:00.1352192 (Total time for all 100 executions)
Когда я запускаю версию с ручной итерацией, первые пять раз выглядят так:
00:00:00.0124269 (after 1st run)
00:00:00.0138497
00:00:00.0152502
00:00:00.0166348
00:00:00.0180180
....
00:00:00.1060389 (Total time for all 100 executions)
У меня будет 30 или 40 разных запросов Linq, которые будут выполняться в разное время. Данные не все поставлены в очередь, и один и тот же запрос выполняется снова и снова. Если я запускаю запрос Linq, а затем выполняю другие действия, и каждый раз, когда я запускаю запрос, это занимает по существу 0,04 секунды, тогда приложение будет работать очень медленно. Если при первом запуске ЛЮБОГО запроса Linq требуется 0,04 секунды, а затем это время больше не повторяется для этого приложения, тогда будет лучше использовать Linq.
Есть ли у кого-то опыт работы с Linq по сравнению с ручной итерацией, и есть ли какие-то рекомендации относительно скорости?