Java: оптимизировать хэш-набор для крупномасштабного обнаружения дубликатов
Я работаю над проектом, где я обрабатываю много твитов; цель заключается в удалении дубликатов по мере их обработки. У меня есть идентификаторы твитов, которые приходят в виде строк формата"166471306949304320"
Я использовалHashSet
для этого, который работает хорошо некоторое время. Но к тому времени, когда я получаю около 10 миллионов единиц товара, я сильно увязаю и в конечном итоге получаю ошибку GC, предположительно из-за перепрошивки. Я попытался определить лучший размер / нагрузку с
tweetids = new HashSet(220000,0.80F);
и это позволяет ему продвинуться немного дальше, но все еще мучительно медленно (примерно на 10 миллионов это занимает в 3 раза больше времени). Как я могу оптимизировать это? Учитывая, что у меня есть приблизительное представление о том, сколько элементов должно быть в наборе к концу (в нашем случае, около 20-22 миллионов), я должен создать HashSet, который перефразирует только два или три раза, или будет издержки для такого Слишком много времени-штрафов? Будет ли все работать лучше, если бы я неt, используя String, или если я определяю другую функцию HashCode (которая, в данном случае конкретного экземпляра String,не знаю как это сделать)? Эта часть кода реализации приведена ниже.
tweetids = new HashSet(220000,0.80F); // in constructor
duplicates = 0;
...
// In loop: For(each tweet)
String twid = (String) tweet_twitter_data.get("id");
// Check that we have not processed this tweet already
if (!(tweetids.add(twid))){
duplicates++;
continue;
}
РЕШЕНИЕ
Благодаря вашим рекомендациям я решил это. Проблема заключалась в количестве памяти, необходимой для хэш-представлений; первый,HashSet
был просто огромен и неуместен, потому чтоString.hashCode()
непомерно для этого масштаба. Затем я попробовал Trie, но он потерпел крах чуть более 1 миллиона записей; перераспределение массивов было проблематичным. Я использовалHashSet
для лучшего эффекта и почти сделал это, но скорость упала, и он, наконец, упал на последнем этапе обработки (около 19 миллионов). Решение пришло с отходом от стандартной библиотеки и использованиемTrove, Он закончил 22 миллиона записей на несколько минут быстрее, чем вообще не проверял дубликаты. Окончательная реализация была простой и выглядела так:
import gnu.trove.set.hash.TLongHashSet;
...
TLongHashSet tweetids; // class variable
...
tweetids = new TLongHashSet(23000000,0.80F); // in constructor
...
// inside for(each record)
String twid = (String) tweet_twitter_data.get("id");
if (!(tweetids.add(Long.parseLong(twid)))) {
duplicates++;
continue;
}