Portál AbcLinuxu, 28. června 2025 21:04
mam mnozinu asi 20mil stringov (dlzka je cca 34 znakov) a hladam sposob ako ich co najrychlejsie porovnat s vygenerovanym stringom.
momentalne to riesim tak, ze stringy mam ulozene v postgresql (samozrejmostou je btree index) a robim SELECT string FROM strings WHERE string='vygenerovany_string'
. Je to bruteforce napisany v c s vyuzitim libpq kniznice, pri ktorom dosahujem cca 170 porovnani/selectov za sekundu.
zda sa mi 170 porovnani za sekundu malo. rad by som toto navysil o niekolko radov a priblizil sa ku 100000 a viac porovnani za sekundu
myslite ze sa to da dosiahnut v beznych domacich podminkach? a ak ano ako by sa to dalo vyriesit?
PS: zacinam uvazovat nad aho-corasick algoritmom ale kjedze nie som developer, bolo by super ine riesenie
Dakujem
#include <iostream> #include <string> #include <functional> #include <algorithm> #include <cstdlib> #include <ctime> std::string some_string() { char result[35]; for (int i = 0; i < 34; i++) { result[i] = ' ' + rand() % 64; } result[34] = 0; return result; } void measure_time(const std::string &label, std::function<void()> f) { clock_t start = clock(); std::cout << label << std::flush; f(); clock_t finish = clock(); std::cout << " - finished in " << ((float)(finish - start)/CLOCKS_PER_SEC) << "s" << std::endl; } int main() { static const int MAX = 20000000; std::string *s = new std::string[MAX]; measure_time("String generation", [&s]() { for (int i = 0; i < MAX; i++) { s[i] = some_string(); } }); measure_time("Sorting", [&s]() { std::sort(s, s+MAX); }); static const int LOOKUP_COUNT = 100000; std::string *lookup = new std::string[LOOKUP_COUNT]; for (int i = 0; i < LOOKUP_COUNT; i++) { lookup[i] = some_string(); } measure_time("Lookup of 100k new strings", [&s, &lookup]() { for (int i = 0; i < LOOKUP_COUNT; i++) { std::binary_search(s, s+MAX, lookup[i]); } }); return 0; }Dostávám:
String generation - finished in 5.90161s Sorting - finished in 14.5592s Lookup of 100k new strings - finished in 0.188295s
set<string>
, bude to hotové na pár řádků a i pokud je nad tím nějaká obsáhlá C logika, tak to stejně nevadí, protože to většinou C++ komilátor zvládne zakomponovat.
Mate pravdu, je to napisane v C a v databaze je len jeden stlpec s mnozinou 20M stringov. Tento jediny stlpec je zaroven aj primarnym klucom.
Pointa mala byt v tom ze databaza si sama vsetko zoptimalizuje a vytvori indexy a hladanie/bruteforce bude velmi rychle. Pre mna ako neprogramatora toto mala byt najlahsia cesta/riesenie
po testoch sa ukazuje ze s roznymi konfiguraciami a optimalizaciami postgresql viem dosiahnut max 170 selectov/pokusov za sekundu
uvazoval som nad aho-corasick algoritmomJako že bys to lineárně prošel? To nebude fungovat - kromě false-positives taky kvůli rychlosti: celé ty tvoje stringy mají 680 MB, a to musíš celé přečíst (a ten automat žere vstup po bajtech). Ostatní vyhledávací struktury mají složitost logaritmickou. qsort + binární vyhledávání snad zvládneš, ne? A pokud se ti ty stringy, ve kterých vyhledáváš, mění (což jsi pořád ještě nenapsal!), použij červeno-černý strom - například ten z tree(3) nebo z libucw.
Tiskni
Sdílej:
ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.