/ Оптимизиращ алгоритъм за намаляване на времевата сложност (използвани редисни типове данни) - алгоритъм, редис

Оптимизиране на алгоритъма, за да се намали сложността на времето (използва се видът на използваните данни) - алгоритъм, redis

Заден план:

В моя уебсайт потребителите създават социалнимрежа. Това причинява известяванията да летят до свързани възли в мрежата. Например искания за приятели, харесвания, коментари, всички генерират уведомление за съответните възли в мрежата.

За да поддържате всичко прозрачно, потребителите могат да виждат съответните си известия като списък в отделен URL адрес. Този списък се захранва от сортиран набор с подновен резерв ss:<user_id>, Сортираният комплект съдържа hash ids, заедно с времето след епохата (като. \ t score). Например:

hash_id              |     updated_at
np:1:0:544           |     1482234321.48124
np:1:2:454           |     1482235629.73111
np:1:1:701           |     1482237000.59143

Също така е и всяко уведомление видян или невидим, Това seen състояние се съхранява в съответния хеш, при ключ s, Например на s въведете хеш np:1:0:544 е False; ни казва, че това е невидимо уведомление.


Предизвикателството:

Предизвикателството е да преброим всички невиждани уведомления отвъд предварително определено време на епохата. Това време се съхранява в отделен наричан брояч cut-off.


Това, което вече правя:

1) Вземете всички hash_ids от ss:<user_id> с резултати по - високи от. \ t cut-off, Например ZRANGEBYSCORE ss:<user_id> (cut-off +inf (in redis parlance).

2) Превъртете през всеки hash_id, като го проверите s ключ (т.е. seen ключ). ако s е False, увеличете брояча. Например правя HGET hash_name s за всеки хеш обект. Ако върнатата стойност е False, incr отделен брояч за пренастройка.

Времевата сложност на стъпка 1 е O(log(N)+M), Това от стъпка 2 е O(M), Може да бъде O(N) при макс.


Какво трябва да подобря:

Има ли някакъв начин да направя това в по-малка времева сложност (напр. O(log(N))? Например чрез използване на композитно индексиране и лексикографска подредба?

Изпълнението е критично; това изчисление се случва ~ 2 милиона пъти дневно на моя уебсайт (и мащабиране), така че търся начини за подобряване на скалируемостта.


Забележка: Разбира се, има и други мерки, които мога да предприема, за да се намали натоварването на този алгоритъм (например намаляване на неговата честота, подобряване на инфраструктурата и т.н.), но това е различно съображение.

Отговори:

0 за отговор № 1

Промених подхода си.

Най- score (Т.е. updated_at) на сортирания набор сега time.time()+SEEN[status] където SEEN={True:2000000000,False:4000000000}, Това автоматично сортира ключовете от видян и невидим, като същевременно запазва информация за времето (придобито от score-SEEN[status]).

Като цяло този подход ми позволи да се отрежастъпка 2 от изчислението. Времевата сложност е до O (log (N)). Голямото отнемане е, че интелигентната формулировка на индекса наистина може да доведе до представяне. За всеки, който се интересува, тук е прочетена информация за това как сложното индексиране може да постигне различни неща.