Мне нужно читать из набора данных, который очень большой, сильно взаимосвязанный, данные довольно локализованы, а чтения довольно дороги.В частности:
- Наборы данных имеют размер от 2 до 30 гигабайт, поэтому я должен отобразить фрагменты файла в память для чтения.Это очень дорого по сравнению с остальной работой, которую я делаю в алгоритме.Из профилирования я обнаружил, что примерно 60% времени тратится на чтение памяти, поэтому это подходящее место для начала оптимизации.
- При работе с частью этого набора данных мне нужно переходить по ссылкам внутриэто (представьте, что это похоже на связанный список), и хотя эти операции чтения не гарантированы почти последовательными, они довольно локализованы.Это означает:
- Скажем, например, мы работаем с 2 мегабайтами памяти одновременно.Если вы прочитаете 2 мегабайта данных в память, примерно 40% операций чтения, которые мне придется впоследствии выполнить, будут в тех же 2 мегабайтах памяти.Примерно 20% операций чтения будут представлять собой чисто произвольный доступ к остальным данным, а остальные 40%, скорее всего, будут связаны с сегментом 2 мегабайта, который указывает на этот.
Из знанияПроблема и из профилирования, я считаю, что введение кэша в программу очень поможет.То, что я хочу сделать, - это создать кеш, который содержит N фрагментов X мегабайтов памяти (N и X настраиваются, чтобы я мог его настроить), и я могу сначала проверить его, прежде чем сопоставлять другой раздел памяти.Кроме того, чем дольше что-то было в кеше, тем меньше вероятность того, что мы будем запрашивать эту память в краткосрочной перспективе, и поэтому самые старые данные должны будут устареть.
После всего этого мой вопросочень просто: Какую структуру данных лучше всего реализовать для кеша такого типа?
Мне нужны очень быстрые поиски, чтобы увидеть, находится ли данный адрес в кеше.С каждым «промахом» кеша я захочу удалить его самый старый член и добавить нового.Однако я планирую попытаться настроить его (изменив объем кэшируемого объема) таким образом, чтобы 70% или более операций чтения были попаданиями.
В настоящее время я думаю использовать дерево AVL (LOG2 n для поиска /вставить / удалить) будет самым безопасным (без вырожденных случаев).Мой другой вариант - разреженная хеш-таблица, так что поиск будет в лучшем случае O (1).Теоретически это может выродиться в O (n), но на практике я мог бы снизить количество столкновений.Здесь возникает вопрос, сколько времени потребуется, чтобы найти и удалить самую старую запись в хеш-таблице.
Есть ли у кого-нибудь какие-либо мысли или предложения по поводу того, какая структура данных будет лучше здесь и почему?