From c0348f3e29cd049313f57ede67f637a4d1cf017a Mon Sep 17 00:00:00 2001 From: Alexander Luzgarev Date: Wed, 24 Jul 2024 19:10:47 +0200 Subject: [PATCH] Improve performance of reading objects --- MatFileHandler/SubsystemDataReader.cs | 87 +++++++++++++++++++++------ 1 file changed, 69 insertions(+), 18 deletions(-) diff --git a/MatFileHandler/SubsystemDataReader.cs b/MatFileHandler/SubsystemDataReader.cs index 229bc82..39ee74b 100644 --- a/MatFileHandler/SubsystemDataReader.cs +++ b/MatFileHandler/SubsystemDataReader.cs @@ -42,7 +42,7 @@ namespace MatFileHandler var embeddedObjectPositionsToValues = ReadEmbeddedObjectPositionsToValues(info, offsets, numberOfEmbeddedObjects); var numberOfObjects = ((offsets[5] - offsets[4]) / 24) - 1; var objectClasses = ReadObjectClassInformations(info, offsets, numberOfObjects); - var numberOfObjectPositions = objectClasses.Values.Count(x => x.ObjectPosition != 0); + var numberOfObjectPositions = objectClasses.NumberOfObjectPositions; var objectPositionsToValues = ReadObjectPositionsToValues(info, offsets, numberOfObjectPositions); var (classInformation, objectInformation) = GatherClassAndObjectInformation( @@ -68,7 +68,7 @@ namespace MatFileHandler return ReadObjectPositionsToValuesMapping(reader, numberOfObjectPositions); } - private static Dictionary ReadObjectClassInformations(byte[] info, int[] offsets, int numberOfObjects) + private static ObjectClasses ReadObjectClassInformations(byte[] info, int[] offsets, int numberOfObjects) { using var stream = new MemoryStream(info, offsets[4], offsets[5] - offsets[4]); using var reader = new BinaryReader(stream); @@ -102,7 +102,7 @@ namespace MatFileHandler GatherClassAndObjectInformation( Dictionary classIdToName, string[] fieldNames, - Dictionary objectClasses, + ObjectClasses objectClasses, Dictionary> objectPositionsToValues, Dictionary> embeddedObjectPositionsToValues) { @@ -113,8 +113,8 @@ namespace MatFileHandler var fieldIds = new SortedSet(); foreach (var objectPosition in objectPositionsToValues.Keys) { - var keyValuePair = objectClasses.First(pair => pair.Value.ObjectPosition == objectPosition); - if (keyValuePair.Value.ClassId != classId) + var foundClassId = objectClasses.GetClassIdByObjectPosition(objectPosition); + if (foundClassId != classId) { continue; } @@ -127,8 +127,8 @@ namespace MatFileHandler foreach (var objectPosition in embeddedObjectPositionsToValues.Keys) { - var keyValuePair = objectClasses.First(pair => pair.Value.EmbeddedObjectPosition == objectPosition); - if (keyValuePair.Value.ClassId != classId) + var foundClassId = objectClasses.GetClassIdByEmbeddedObjectPosition(objectPosition); + if (foundClassId != classId) { continue; } @@ -151,15 +151,14 @@ namespace MatFileHandler var objectInfos = new Dictionary(); foreach (var objectPosition in objectPositionsToValues.Keys) { - var keyValuePair = objectClasses.First(pair => pair.Value.ObjectPosition == objectPosition); - objectInfos[keyValuePair.Key] = new SubsystemData.ObjectInfo(objectPositionsToValues[objectPosition]); + var foundKey = objectClasses.GetKeyByObjectPosition(objectPosition); + objectInfos[foundKey] = new SubsystemData.ObjectInfo(objectPositionsToValues[objectPosition]); } - foreach (var objectPosition in embeddedObjectPositionsToValues.Keys) + foreach (var embeddedObjectPosition in embeddedObjectPositionsToValues.Keys) { - var keyValuePair = objectClasses.First(pair => pair.Value.EmbeddedObjectPosition == objectPosition); - objectInfos[keyValuePair.Key] = - new SubsystemData.ObjectInfo(embeddedObjectPositionsToValues[objectPosition]); + var foundKey = objectClasses.GetKeyByEmbeddedObjectPosition(embeddedObjectPosition); + objectInfos[foundKey] = new SubsystemData.ObjectInfo(embeddedObjectPositionsToValues[embeddedObjectPosition]); } return (classInfos, objectInfos); @@ -241,24 +240,40 @@ namespace MatFileHandler return result; } - private static Dictionary ReadObjectClasses( + private static ObjectClasses ReadObjectClasses( BinaryReader reader, int numberOfObjects) { var result = new Dictionary(); + var classIdFromObjectPosition = new Dictionary(); + var classIdFromEmbeddedObjectPosition = new Dictionary(); + var keyFromObjectPosition = new Dictionary(); + var keyFromEmbeddedObjectPosition = new Dictionary(); reader.ReadBytes(24); + var numberOfObjectPositions = 0; for (var i = 0; i < numberOfObjects; i++) { var classId = reader.ReadInt32(); reader.ReadBytes(8); var embeddedObjectPosition = reader.ReadInt32(); var objectPosition = reader.ReadInt32(); - var loadingOrder = reader.ReadInt32(); - result[i + 1] = - new ObjectClassInformation(embeddedObjectPosition, objectPosition, loadingOrder, classId); + var loadingOrder = reader.ReadInt32(); // Not used. + classIdFromObjectPosition[objectPosition] = classId; + classIdFromEmbeddedObjectPosition[embeddedObjectPosition] = classId; + keyFromObjectPosition[objectPosition] = i + 1; + keyFromEmbeddedObjectPosition[embeddedObjectPosition] = i + 1; + if (objectPosition != 0) + { + numberOfObjectPositions++; + } } - return result; + return new ObjectClasses( + classIdFromObjectPosition, + classIdFromEmbeddedObjectPosition, + keyFromObjectPosition, + keyFromEmbeddedObjectPosition, + numberOfObjectPositions); } private static Dictionary> ReadObjectPositionsToValuesMapping( @@ -344,5 +359,41 @@ namespace MatFileHandler public int ObjectPosition { get; } } + + private class ObjectClasses + { + private readonly Dictionary _classIdFromObjectPosition; + private readonly Dictionary _classIdFromEmbeddedObjectPosition; + private readonly Dictionary _keyFromObjectPosition; + private readonly Dictionary _keyFromEmbeddedObjectPosition; + + public ObjectClasses( + Dictionary classIdFromObjectPosition, + Dictionary classIdFromEmbeddedObjectPosition, + Dictionary keyFromObjectPosition, + Dictionary keyFromEmbeddedObjectPosition, + int numberOfObjectPositions) + { + _classIdFromObjectPosition = classIdFromObjectPosition; + _classIdFromEmbeddedObjectPosition = classIdFromEmbeddedObjectPosition; + _keyFromObjectPosition = keyFromObjectPosition; + _keyFromEmbeddedObjectPosition = keyFromEmbeddedObjectPosition; + NumberOfObjectPositions = numberOfObjectPositions; + } + + public int NumberOfObjectPositions { get; } + + public int GetClassIdByObjectPosition(int objectPosition) + => _classIdFromObjectPosition[objectPosition]; + + public int GetClassIdByEmbeddedObjectPosition(int embeddedObjectPosition) + => _classIdFromEmbeddedObjectPosition[embeddedObjectPosition]; + + public int GetKeyByObjectPosition(int objectPosition) + => _keyFromObjectPosition[objectPosition]; + + public int GetKeyByEmbeddedObjectPosition(int embeddedObjectPosition) + => _keyFromEmbeddedObjectPosition[embeddedObjectPosition]; + } } } \ No newline at end of file