Хэш-коды для неизменных типов

Как обычно, здесь также есть отличный модуль CPAN: Bit :: Vector .

Преобразование будет выглядеть примерно так:

use Bit::Vector;

my $v = Bit::Vector->new_Bin( 32, '0001001100101' );
print "hex: ", $v->to_Hex(), "\n";
print "dec: ", $v->to_Dec(), "\n";

Бинарные строки могут быть практически любой длины, и вы можете делать другие полезные вещи, такие как сдвиг битов и т. Д.

5
задан GEOCHET 23 June 2009 в 17:37
поделиться

7 ответов

Обычно я бы не создавал его в конструкторе, но я бы также хотел узнать больше об ожидаемом использовании, прежде чем решать, кэшировать его или нет.

Вы ожидаете небольшое количество экземпляров, которые сильно хешируются и для которых требуется много времени для вычисления хеша? В таком случае может потребоваться кеширование. Если вы ожидаете большого количества потенциально «выброшенных» экземпляров, я бы не стал беспокоиться о кешировании.

Интересно, что .NET и Java сделали другой выбор для String в этом отношении - Java кэширует хеш, .NET - нет. т. Учитывая, что многие экземпляры строк никогда не хешируются, а те, которые хешируются , часто хешируются только один раз (например, при вставке в хеш-таблицу), я думаю, что я поддерживаю решение .NET здесь.

В основном вы повторная торговля памятью + сложность против скорости. Как говорит Майкл, протестируйте, прежде чем усложнять код. Конечно, в некоторых случаях (например, для библиотеки классов) вы не можете точно предсказать использование в реальном мире, но во многих ситуациях у вас будет довольно хорошая идея.

Конечно, вам не нужно отдельное свойство, хотя . Хеш-коды всегда должны оставаться неизменными, если кто-то не изменит состояние объекта - а если ваш тип неизменяемый, вы уже это запрещаете, поэтому пользователю не следует ожидать каких-либо изменений. Просто переопределите GetHashCode () .

Вам, конечно, не нужно отдельное свойство. Хеш-коды всегда должны оставаться неизменными, если кто-то не изменит состояние объекта - а если ваш тип неизменяемый, вы уже это запрещаете, поэтому пользователю не следует ожидать каких-либо изменений. Просто переопределите GetHashCode () .

Вам, конечно, не нужно отдельное свойство. Хеш-коды всегда должны оставаться неизменными, если кто-то не изменит состояние объекта - а если ваш тип неизменяемый, вы уже это запрещаете, поэтому пользователю не следует ожидать каких-либо изменений. Просто переопределите GetHashCode () .

9
ответ дан 18 December 2019 в 05:23
поделиться

Я бы сгенерировал хэш-код один раз, когда getHashCode вызывается в первый раз, а затем кэширую его для последующих вызовов. Это позволяет избежать его вызова в конструкторе, когда он может не понадобиться.

Если вы не ожидаете вызывать getHashCode очень много раз для каждого объекта значения, возможно, вам вообще не нужно кэшировать значение .

4
ответ дан 18 December 2019 в 05:23
поделиться

Почему вам нужно убедиться, что хэш-код исправлен? Семантика хэш-кода заключается в том, что он всегда будет одним и тем же значением для любого заданного состояния объекта. Поскольку ваши объекты неизменны, это само собой разумеющееся. Как вы решите внедрить GetHashCode, зависит от вас.

Возможность вернуть частное поле - это один из возможных вариантов - он маленький, простой и быстрый.

1
ответ дан 18 December 2019 в 05:23
поделиться

Ну, у вас должен быть переопределенный метод GetHashCode (), поскольку именно так потребители будут получать ваш хэш-код. Большинство хэш-кодов представляют собой довольно простые арифметические операции, которые выполняются быстро. Есть ли у вас причина полагать, что кэширование результатов (которое требует затрат памяти) даст вам заметное улучшение производительности?

Начните с простого - генерируйте хэш-код на лету. Если вы думаете, что заметите улучшения производительности при кэшировании, сначала протестируйте.

Правила требуют, чтобы я отсылал вас к цитате «преждевременная оптимизация - корень всех зол».

3
ответ дан 18 December 2019 в 05:23
поделиться

In general, computing the HashCode should be fast. So caching should not be much of an optimization, and not worth the trouble.

If profiling really shows that GethashCode takes a significant amount of time then maybe you should cache it, as a fix.

But I wouldn't consider it part of the normal practice.

1
ответ дан 18 December 2019 в 05:23
поделиться

Я знаю по своему личному опыту, что разработчики действительно хороши в неверной оценке проблем производительности .

Поэтому рекомендуется сделать все максимально простым при вычислении хэш-кода на лету в GetHashCode ().

2
ответ дан 18 December 2019 в 05:23
поделиться

Есть ли какие-либо соображения относительно неизменяемых типов относительно хэш-кодов?

Неизменяемые типы - это самые простые типы для правильного хеширования; большинство ошибок хэш-кода происходит при хешировании изменяемых данных. Самое главное, что хеширование и равенство совпадают; если два экземпляра сравниваются как равные, они должны иметь одинаковый хэш-код. (Обратное не всегда верно; два экземпляра с одинаковым хешем не обязательно должны быть равны. )

Должен ли я сгенерировать его один раз в конструкторе?

Это метод оптимизации производительности; тем самым вы обмениваете увеличенное потребление пространства (для хранения вычисленного значения) на возможное сокращение времени. Я никогда не занимаюсь оптимизацией производительности, если она не основана на реалистичных, ориентированных на клиента тестах производительности, которые тщательно измеряют производительность обоих вариантов относительно задокументированных целей. Вам следует сделать это, если ваши тщательно спланированные эксперименты показывают, что (1) невыполнение этого требования приводит к тому, что вы упускаете свою цель, и (2) выполнение этого заставляет вас достигать своей цели.

Как бы вы дали понять, что хеш-код исправлен?

Я не понимаю вопроса. Изменение хеш-кода - это исключение, а не правило. Хэш-коды всегда должны быть неизменными. Если хэш-код объекта изменяется, объект может «потеряться» в хеш-таблице, поэтому каждый должен предполагать, что хеш-коды остаются стабильными.

не лучше ли использовать свойство под названием HashCode вместо метода GetHashCode?

Какой потребитель вашего объекта скажет: «Ну, я мог бы вызвать GetHashCode (), метод, который гарантированно работает для всех объектов, но вместо этого я собираюсь вызвать этот геттер HashCode, который делает то же самое»? Вы имеете в виду такого потребителя?

Если у вас нет потребителей функциональности, не предоставляйте их.

вместо метода GetHashCode?

Какой потребитель вашего объекта скажет: «Ну, я мог бы вызвать GetHashCode (), метод, гарантированно работающий для всех объектов, но вместо этого я собираюсь вызвать этот метод получения HashCode, который точно выполняет тоже самое" ? Вы имеете в виду такого потребителя?

Если у вас нет потребителей функциональности, не предоставляйте их.

вместо метода GetHashCode?

Какой потребитель вашего объекта скажет: «Ну, я мог бы вызвать GetHashCode (), метод, гарантированно работающий для всех объектов, но вместо этого я собираюсь вызвать этот метод получения HashCode, который точно выполняет тоже самое" ? Вы имеете в виду такого потребителя?

Если у вас нет потребителей функциональности, не предоставляйте их.

18
ответ дан 18 December 2019 в 05:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: