Если значения хешируются, самым простым и тупым способом удаления дубликатов является использование set
:
values = mygenerator()
unique_values = set(values)
Но не смотрите: наборы не помнят, какой порядок были изначально выбраны in. Таким образом, это скремблирует последовательность.
Функция ниже может быть лучше, чем set
для вашей цели. Он отфильтровывает дубликаты, не вызывая каких-либо из других значений:
def nub(it):
seen = set()
for x in it:
if x not in seen:
yield x
seen.add(x)
Вызов nub
с одним аргументом, любым итерабельным значениями хеширования. Он возвращает итератор, который создает все те же элементы, но с удалением дубликатов.
Для Ваших потребностей используйте ConcurrentHashMap
. Это позволяет параллельную модификацию Карты от нескольких потоков без потребности заблокировать их. Collections.synchronizedMap(map)
создает блокирующуюся Карту, которая ухудшит производительность, хотя гарантируют непротиворечивость (если используется правильно).
Использование вторая опция, если необходимо гарантировать непротиворечивость данных и каждый поток, должна иметь актуальное представление карты. Используйте первое, если производительность очень важна, и каждый поток только вставляет данные в карту с чтениями, происходящими менее часто.
ConcurrentHashMap оптимизирован для параллельного доступа.
Доступы не блокируют целую карту, но используют более прекрасную гранулярную стратегию, которая улучшает масштабируемость. Существуют также функциональные enhanvements специально для параллельного доступа, например, параллельных итераторов.
Вы правы приблизительно HashTable
, можно забыть об этом.
Ваша статья упоминает то, что, в то время как HashTable и синхронизируемый класс обертки обеспечивают основную потокобезопасность, только позволяя один поток за один раз получить доступ к карте, это не 'истинная' потокобезопасность, так как много составных операций все еще требуют дополнительной синхронизации, например:
synchronized (records) {
Record rec = records.get(id);
if (rec == null) {
rec = new Record(id);
records.put(id, rec);
}
return rec;
}
Однако не думают, что ConcurrentHashMap
простая альтернатива для HashMap
с типичным synchronized
блок как показано выше. Читайте этот статья для понимания ее запутанности лучше.
ConcurrentHashMap предпочтен, когда можно использовать его - хотя он требует, по крайней мере, Java 5.
Это разработано для масштабирования хорошо при использовании несколькими потоками. Производительность может быть незначительно более плохой, когда только единственный поток получает доступ к Карте за один раз, но значительно лучше когда несколько потоков получают доступ к карте одновременно.
я нашел запись в блоге , который воспроизводит таблицу от превосходного книжного Параллелизма Java На практике , который я полностью рекомендую.
Collections.synchronizedMap имеет смысл действительно, только если необходимо обернуть карту некоторыми другими характеристиками, возможно, своего рода заказанную карту, как TreeMap.
"Проблемы масштабируемости" для Hashtable
присутствуют точно таким же образом в Collections.synchronizedMap(Map)
- они используют очень простую синхронизацию, что означает, что только один поток может получить доступ к карте одновременно.
Это не большая часть проблемы, когда у Вас есть простые вставки и поиски (если Вы не делаете это чрезвычайно интенсивно), но становится большой проблемой, когда необходимо выполнить итерации по всей Карте, которая может занять много времени для большой Карты - в то время как один поток делает это, все другие должны ожидать, если они хотят вставить или поиск что-нибудь.
ConcurrentHashMap
использование очень сложные методы, чтобы уменьшить потребность в синхронизации и позволить параллельный доступ для чтения несколькими потоками без синхронизации и, что еще более важно, обеспечивают Iterator
, который не требует никакой синхронизации и даже позволяет Карте быть измененной во время взаимодействия (хотя это не делает гарантий, будут ли элементы, которые были вставлены во время повторения, возвращены).
Hashtable
и ConcurrentHashMap
не позволяют null
ключи или null
значения.
Collections.synchronizedMap(Map)
синхронизируется весь операции (get
, put
, size
, и т.д.).
ConcurrentHashMap
поддержки полный параллелизм извлечений и корректируемый ожидаемый параллелизм для обновлений.
, Как обычно, существует параллелизм - наверху - включенные компромиссы скорости. Действительно необходимо полагать, что подробные требования параллелизма приложения принимают решение, и затем тестируют код, чтобы видеть, достаточно хорошо ли это.