У меня есть C#-Application, который хранит данные от TextFile в Объекте Словаря. Объем данных, который будет сохранен, может быть довольно большим, таким образом, требуется много времени, вставляя записи. Со многими объектами в Словаре это становится еще хуже из-за изменения размеров внутреннего массива, который хранит данные для Словаря. Таким образом, я инициализировал Словарь с количеством объектов, которые будут добавлены, но это не оказывает влияния на скорость.
Вот моя функция:
private Dictionary<IdPair, Edge> AddEdgesToExistingNodes(HashSet<NodeConnection> connections)
{
Dictionary<IdPair, Edge> resultSet = new Dictionary<IdPair, Edge>(connections.Count);
foreach (NodeConnection con in connections)
{
...
resultSet.Add(nodeIdPair, newEdge);
}
return resultSet;
}
В моих тестах я вставляю ~300k объекты. Я проверил время выполнения с Профилировщиком Производительности МУРАВЬЕВ и нашел, что Среднее время для набора результатов. Добавьте (...) не изменяется, когда я инициализирую Словарь с необходимым размером. Это совпадает с, когда я инициализирую Словарь с новым Словарем (); (приблизительно 0,256 мс в среднем для каждого Добавляют). Это определенно вызывается объемом данных в Словаре (ХОТЯ я инициализировал его с желаемым размером). Для первых 20k объектов Добавляет среднее время для, 0,03 мс для каждого объекта.
Какая-либо идея, как сделать добавлять-операцию быстрее?
Заранее спасибо, Frank
Вот моя IdPair-структура:
public struct IdPair
{
public int id1;
public int id2;
public IdPair(int oneId, int anotherId)
{
if (oneId > anotherId)
{
id1 = anotherId;
id2 = oneId;
}
else if (anotherId > oneId)
{
id1 = oneId;
id2 = anotherId;
}
else
throw new ArgumentException("The two Ids of the IdPair can't have the same value.");
}
}
Поскольку у вас структура, вы получаете реализацию Equals() и GetHashCode() по умолчанию. Как отмечали другие, это не очень эффективно, поскольку использует отражение, но я не думаю, что проблема в отражении.
Мое предположение заключается в том, что ваши хэш-коды распределяются неравномерно с помощью стандартного GetHashCode(), что может произойти, например, если реализация по умолчанию возвращает простое XOR всех членов (в этом случае hash(a, b) == hash(b, a)). Я не могу найти документацию о том, как реализована функция ValueType.GetHashCode(), но попробуйте добавить
public override int GetHashCode() {
return oneId << 16 | (anotherId & 0xffff);
}
что может быть лучше.
IdPair
- это структура
, и вы не переопределили Equals
или GetHashCode
. Это означает, что будет использоваться реализация этих методов по умолчанию.
Для типов значений реализация по умолчанию Equals
и GetHashCode
использует отражение, что, вероятно, приведет к снижению производительности. Попробуйте предоставить собственную реализацию методов и посмотрите, поможет ли это.
Предлагаемая мной реализация, возможно, это не совсем то, что вам нужно / нужно:
public struct IdPair : IEquatable<IdPair>
{
// ...
public override bool Equals(object obj)
{
if (obj is IdPair)
return Equals((IdPair)obj);
return false;
}
public bool Equals(IdPair other)
{
return id1.Equals(other.id1)
&& id2.Equals(other.id2);
}
public override int GetHashCode()
{
unchecked
{
int hash = 269;
hash = (hash * 19) + id1.GetHashCode();
hash = (hash * 19) + id2.GetHashCode();
return hash;
}
}
}