2015-03-13 9 views
1

Мне было интересно, какой был бы оптимальный способ вычисления хэша, учитывая, что значения ptime, которые используются в качестве ключа, отличаются в основном часами и дата (минуты и секунды обычно 0).Functor for std :: hash <boost :: posix_time :: ptime>

Я сделал это, но я чувствую, что это довольно некрасиво и медленно:

namespace std 
{ 
    /** 
    * Specialize std::hash for ptime 
    */ 
    template<> 
    class hash<boost::posix_time::ptime> 
    { 
    public: 
     size_t operator()(const boost::posix_time::ptime& t) const 
     { 
      const auto dt = t.date(); 
      const auto ho = t.time_of_day().hours(); 
      return hash<int>()(dt.day_number())^hash<int>()(ho); 
     } 
    }; 
} 

ответ

4

ключевые слова вы должны искать являются «avalanche effect» и «хэш-комбинат».

Вы, вероятно, не должны самостоятельно создавать функцию хэша, так как эта область тщательно изучена и изучена. Просто выберите функцию с хорошим лавинным эффектом, например, MurmurHash.

Поскольку вы уже используете импульс, то boost::hash_combine может быть наиболее подходящим и полезным для Вас решение (also mentioned here):

friend std::size_t hash_value(point const& p) 
{ 
    std::size_t seed = 0; 
    boost::hash_combine(seed, p.x); 
    boost::hash_combine(seed, p.y); 
    return seed; 
} 

Более важным, вместо того, чтобы использовать DAY_NUMBER и часы, вы можете использовать что-то вроде total_nanoseconds() или даже перейти к внутреннему типу системы и использовать это значение для хэширования, избегая сокращения искусственного диапазона при преобразовании реальной временной метки в дни/часы.

+0

Не total_nanoseconds() от time_duration -not ptime? поэтому его можно было бы получить только с time_of_day(), не так ли? – huff

+0

Вы правы, я посмотрел на неправильный абзац в документации. Но у вас возникла идея: лучше расширить диапазон ввода хэша на миллисекунды или тики, чтобы результат был лучше распределен. –