Улучшение производительности сериализации / хэш-функции - PullRequest
4 голосов
/ 11 ноября 2011

Я работаю над специализированной хэш-таблицей на диске (предыдущие эксперименты с Berkeley, ManagedESENT и т. Д. Не увенчались успехом). Он имеет довольно простую цепочечную структуру, в которой каждая пара ключ-значение (KVP) сопровождается в файле длинным значением (Int64), которое указывает на следующий KVP в цепочке (и использует нулевое значение, если его нет). ). Я использую MD5 для генерации хеш-кода.

При профилировании кода для оценки скорости добавления записей хеш-функция отвечает за около 55% времени выполнения, что неудивительно. Но около 25% того времени приходит от вызова binForm.Serialize(ms, obj) в функции сериализации ObjectToByteArray. Обе функции показаны ниже. Я предполагаю, что не могу добиться больших успехов в самом хэш-алгоритме, но мне интересно, смогу ли я получить какую-то производительность от функции сериализации?

    // Compute hash code
    long hash(object s)
    {
        byte[] y = md5.ComputeHash(ObjectToByteArray(s)); // Produces byte[16]
        long z = BitConverter.ToInt64(y, 0);
        long res = z & bitMask;
        return res;
    }

    // Convert an object to a byte array
    private byte[] ObjectToByteArray(Object obj)
    {
        if (obj == null)
            return null;

        MemoryStream ms = new MemoryStream();
        binForm.Serialize(ms, obj);
        return ms.ToArray();
    }

Ответы [ 2 ]

2 голосов
/ 11 ноября 2011

Используйте protobuf.net, найдено здесь , это намного быстрее!

Обновление

Судя по вашему коду, я полагаю, что нет требования, чтобы вычисленные хэши были согласованы между доменами приложений? Если вы не вычисляете ваш HashCode, то можете просто:

private static long GenerateHash(object key)
{
  long typeHash = key.GetType().GetHashCode();
  long keyHash = key.GetHashCode();
  return (typeHash << 32) + keyHash;
}

Для дальнейшего использования ваш MemoryStream действительно должен быть в блоке использования, иначе вы рискуете утечка памяти:

private byte[] ObjectToByteArray(Object obj)
{
    if (obj == null)
        return null;

    using (MemoryStream ms = new MemoryStream()) 
    {
      binForm.Serialize(ms, obj);
      return ms.ToArray();
    }   
}
0 голосов
/ 11 ноября 2011

двоичный форматер известен своей медленной работой.попробуй другие методы сериализации.

...