Очень низкая производительность с шейп-файлом DotSpatial
Я пытаюсь прочитать все данные объекта из определенного шейп-файла. В этом случае я использую DotSpatial для открытия файла и перебираю функции. Этот конкретный шейп-файл имеет размер всего 9 МБ, а файл DBF - 14 МБ. Существует около 75 тыс. Функций для прохождения.
Обратите внимание, что все это программно через консольное приложение, так что здесь нет рендеринга или чего-либо еще.
При загрузке файла формы, я перепроектирую, затем я повторяю. Загрузка перепроектирования супер быстрая. Однако, как только код достигает моего блока foreach, загрузка данных занимает около 2 полных минут, а при отладке в VisualStudio используется примерно 2 ГБ памяти. Это кажется очень, очень чрезмерным для того, что является достаточно маленьким файлом данных.
Я запускал тот же код за пределами Visual Studio, из командной строки, однако время по-прежнему составляет примерно 2 полных минуты и около 1,3 ГБ памяти для процесса.
Есть ли способ ускорить это вообще?
Ниже мой код:
// Load the shape file and project to GDA94
Shapefile indexMapFile = Shapefile.OpenFile(shapeFilePath);
indexMapFile.Reproject(KnownCoordinateSystems.Geographic.Australia.GeocentricDatumofAustralia1994);
// Get's slow here and takes forever to get to the first item
foreach(IFeature feature in indexMapFile.Features)
{
// Once inside the loop, it's blazingly quick.
}
Интересно, что когда я использую непосредственное окно VS, это супер супер быстро, без задержки вообще...
2 ответа
Это имеет ту же проблему для очень больших файлов (1,2 миллиона функций), заполнение коллекций.Features никогда не заканчивается.
Но если вы запрашиваете эту функцию, у вас нет памяти или задержек.
int lRows = fs.NumRows();
for (int i = 0; i < lRows; i++)
{
// Get the feature
IFeature pFeat = fs.GetFeature(i);
StringBuilder sb = new StringBuilder();
{
sb.Append(Guid.NewGuid().ToString());
sb.Append("|");
sb.Append(pFeat.DataRow["MAPA"]);
sb.Append("|");
sb.Append(pFeat.BasicGeometry.ToString());
}
pLinesList.Add(sb.ToString());
lCnt++;
if (lCnt % 10 == 0)
{
pOld = Console.ForegroundColor;
Console.ForegroundColor = ConsoleColor.DarkGreen;
Console.Write("\r{0} de {1} ({2}%)", lCnt.ToString(), lRows.ToString(), (100.0 * ((float)lCnt / (float)lRows)).ToString());
Console.ForegroundColor = pOld;
}
}
Ищите метод GetFeature.
Мне удалось выяснить это...
По какой-то причине вызов foreach по функциям мучительно медленен.
Однако, поскольку эти файлы имеют сопоставление 1-1 с объектами - строками данных (у каждого объекта есть соответствующая строка данных), я немного изменил его следующим образом. Теперь это очень быстро... меньше секунды, чтобы начать итерации.
// Load the shape file and project to GDA94
Shapefile indexMapFile = Shapefile.OpenFile(shapeFilePath);
indexMapFile.Reproject(KnownCoordinateSystems.Geographic.Australia.GeocentricDatumofAustralia1994);
// Get the map index from the Feature data
for(int i = 0; i < indexMapFile.DataTable.Rows.Count; i++)
{
// Get the feature
IFeature feature = indexMapFile.Features.ElementAt(i);
// Now it's very quick to iterate through and work with the feature.
}
Интересно, почему это так? Я думаю, что мне нужно посмотреть на итератор в реализации IFeatureList.
Ура, Джастин