Autor Téma: Benchmark: Dictionary vs StringList vs HashedStringList vs SQLite in Memory  (Přečteno 874 krát)

Offline Miroslav Baláž

  • Plnoletý
  • ***
  • Příspěvků: 119
  • Karma: 4
    • Verze Delphi: D1,2,3,4,7,2005,2009, XE8,S,B,T10.2.2 Pro
Prehľadávanie zoznamu (text), za rovnakých podmienok. Nástroje zoradené podľa dosiahnutého výsledku :
Kód: HTML [Vybrat]
  1. TDictionary
  2. THashedStringList(je deklarovaný v IniFiles)
  3. SQLite (inMemory)
  4. TStringList
Výsledky sú dramaticky rozdielne. Podrobnosti v priloženom obrázku.
TDictionary všetkých jasne valcuje.
Oba StringList-y boli sorted a vyhľadávalo sa cez IndexOf, čo ešte neznamená, že už máme aj hodnotu TRecord z pointera
Zaujímavé, že HashedStringList bol takmer 100x rýchlejší ako StringList
SQLite (InMemory), sa drží voči StringListu veľmi dobre, ale inak za prvými dvoma zaostáva veru hodne.
SQLite vyhľadávanie :
Kód: MySQL [Vybrat]
  1. SELECT eCategSet, eFnFlagSet FROM sumar WHERE wordItem=?
SQLiteStatement bol Prepared
Kód: MySQL [Vybrat]
  1. CREATE TABLE if not exists [sumar] ( wordItem varchar( 64 ) PRIMARY KEY NOT NULL COLLATE BINARY, eCategSet INT64, eFnFlagSet INTEGER
Nepoužil som Komponenty FireDAC. Napríklad FDMemTable.
Možno má zabudované nejaké optimalizácie. Ale je len málo pravdepodobné, že by porazila v rýchlosti TDictionary
« Poslední změna: 16-12-2017, 19:15:16 od mibainfo »

Offline Miroslav Baláž

  • Plnoletý
  • ***
  • Příspěvků: 119
  • Karma: 4
    • Verze Delphi: D1,2,3,4,7,2005,2009, XE8,S,B,T10.2.2 Pro
Íííha:
Rozdiel medzi týmto (PRIMARY KEY):
Kód: MySQL [Vybrat]
  1. CREATE TABLE [sumar] ( wordItem varchar( 64 ) PRIMARY KEY NOT NULL COLLATE BINARY, eCategSet INT64, eFnFlagSet INTEGER
Nepoužil som Komponenty FireDAC. Napríklad FDMemTable.
Možno má zabudované nejaké optimalizácie. Ale je len málo pravdepodobné, že by porazila v rýchlosti TDictionary
a týmto (Bez Indexu)
Kód: MySQL [Vybrat]
  1. CREATE TABLE [sumar] ( wordItem varchar( 64 ) NOT NULL COLLATE BINARY, eCategSet INT64, eFnFlagSet INTEGER
je 10 násobok.
Prvé 406 milisekúnd, druhé 4773.
Teda s Primary key je výsledok viac ako 10-krát rýchlejší.

Toto je prakticky rovnako rýchle ako PRIMARY KEY ( wordItem ako UNIQUE a UNIQUE INDEX )
Kód: MySQL [Vybrat]
  1. CREATE TABLE [sumar] ( wordItem varchar( 64 ) UNIQUE ON CONFLICT ABORT NOT NULL, eCategSet INT64, eFnFlagSet INTEGER );
  2. CREATE UNIQUE INDEX sumarIdx ON [sumar] (wordItem ASC)

Dokonca aj bez indexu, stačilo iba pole definované ako UNIQUE a trvanie je len 396 milissekúnd:
Kód: MySQL [Vybrat]
  1. CREATE TABLE if not exists [sumar] ( wordItem varchar( 64 ) UNIQUE NOT NULL, eCategSet INT64, eFnFlagSet INTEGER );
Podotýkam, že databáza je InMemory a po každom spustení sa začína bez tabuliek

Prikladám doplnenú tabuľku.
« Poslední změna: 16-12-2017, 21:52:00 od mibainfo »

Online Delfin

  • Guru
  • *****
  • Příspěvků: 546
  • Karma: 26
  • SW konzultant
    • Verze Delphi: 2009, Tokyo
Zajimave. Jen se v tom nejak nedokazu zorientovat. Kolik tedy bylo polozek v kolekcich a jak dlouhy klic? Mohli bychom ziskat ke stazeni testovaci aplikaci?
Shiny disco balls! I don't like :)

Offline Miroslav Baláž

  • Plnoletý
  • ***
  • Příspěvků: 119
  • Karma: 4
    • Verze Delphi: D1,2,3,4,7,2005,2009, XE8,S,B,T10.2.2 Pro
Pre zaujímavosť prikladám aj test pre FIREBIRD 3.0 EMBEDED
Čas bol poslabší cca 29 000 milisekúnd.
Kód: MySQL [Vybrat]
  1. CREATE TABLE sumar ( wordItem varchar( 64 ) NOT NULL primary key, eCategSet BIGINT, eFnFlagSet INTEGER );
Kód som nevedel lepšie než takto:
Kód: Delphi [Vybrat]
  1.   stw.Reset;
  2.   stw.Start;
  3.   dm.qry.Params.Clear;
  4.   dm.qry.SQL.Text := 'select eCategSet, eFnFlagSet from sumar where wordItem = ?';
  5.   dm.qry.Params[ 0 ].DataType := ftString;
  6.   dm.qry.Params[ 0 ].Size := 64;
  7.   dm.qry.Params[ 0 ].IsCaseSensitive := false;
  8.   dm.qry.Prepare;
  9.   k := 0;
  10.   with dm.qry do
  11.     for i := 1 to 50000 do
  12.       begin
  13.       Params[ 0 ].AsString := 'oxymoron';
  14.       Active := true;
  15.       if not eof then
  16.         Inc( k );
  17.       Active := False;
  18. ..  // Dalsie slova. Natvrdo nakodovane, tak ako ten oxymoron. Zoznam je nizsie
  19.       end;
  20.  
  21.   stw.Stop;
  22.   imilisec := stw.ElapsedMilliseconds;     // 28900
Hľadalo sa v cykle týchto 7 slov :
'oxymoron','query','abcd','#endwhile','date','vba_bitwise','current_timestamp'
Cyklus bol:
For i = 1  to 50 000
Dictionary/resp. Tabulka, obsahuje celkom 221 slov.

Online Delfin

  • Guru
  • *****
  • Příspěvků: 546
  • Karma: 26
  • SW konzultant
    • Verze Delphi: 2009, Tokyo
Pre zaujímavosť prikladám aj test pre FIREBIRD 3.0 EMBEDED
Čas bol poslabší cca 29 000 milisekúnd.
Kód: MySQL [Vybrat]
  1. CREATE TABLE sumar ( wordItem varchar( 64 ) NOT NULL primary key, eCategSet BIGINT, eFnFlagSet INTEGER );
Kód som nevedel lepšie než takto:
Kód: Delphi [Vybrat]
  1.   stw.Reset;
  2.   stw.Start;
  3.   dm.qry.Params.Clear;
  4.   dm.qry.SQL.Text := 'select eCategSet, eFnFlagSet from sumar where wordItem = ?';
  5.   dm.qry.Params[ 0 ].DataType := ftString;
  6.   dm.qry.Params[ 0 ].Size := 64;
  7.   dm.qry.Params[ 0 ].IsCaseSensitive := false;
  8.   dm.qry.Prepare;
  9.   k := 0;
  10.   with dm.qry do
  11.     for i := 1 to 50000 do
  12.       begin
  13.       Params[ 0 ].AsString := 'oxymoron';
  14.       Active := true;
  15.       if not eof then
  16.         Inc( k );
  17.       Active := False;
  18. ..  // Dalsie slova. Natvrdo nakodovane, tak ako ten oxymoron. Zoznam je nizsie
  19.       end;
  20.  
  21.   stw.Stop;
  22.   imilisec := stw.ElapsedMilliseconds;     // 28900
Hľadalo sa v cykle týchto 7 slov :
'oxymoron','query','abcd','#endwhile','date','vba_bitwise','current_timestamp'
Cyklus bol:
For i = 1  to 50 000
Dictionary/resp. Tabulka, obsahuje celkom 221 slov.

Ty mu ublizujes :) Dataset otevri a men jen parametr a volej Refresh. Ale zpet k tomu benchmarku - prijemne me prekvapilo ze je hashovani rychlejsi nez hledani pulenym intervalem s tak malym poctem polozek.

Jinak samozrejme hledani indexovaneho sloupce bude rychlejsi nez bez nej. K tomu index existuje. Ale hledani bude pomalejsi nez nativni kolekce (index bude totiz zase jen hash kolekce). Pujde tam o overhead v podobe volani klientske knihovny - tady neverim ze by nekdo v DBMS dokazal implemetovat mnohem rychlejsi hash kolekci nez ma Delphi.

P.S. stopky se daji vytvorit jednou metodou, StartNew.
« Poslední změna: 17-12-2017, 01:01:29 od Delfin »
Shiny disco balls! I don't like :)

Offline Miroslav Baláž

  • Plnoletý
  • ***
  • Příspěvků: 119
  • Karma: 4
    • Verze Delphi: D1,2,3,4,7,2005,2009, XE8,S,B,T10.2.2 Pro
Delfin dík  :)
Tvoj návrh výrazne pomohol: čas sa skrátil na tretinu pôvodného: 9 713 ms  vs 29 700
Kód: Delphi [Vybrat]
  1.   stw.Reset;
  2.   stw.Start;
  3.   dm.qry.Params.Clear;
  4.   dm.qry.SQL.Text := 'select eCategSet, eFnFlagSet from sumar where wordItem = ?';
  5.   dm.qry.Params[ 0 ].DataType := ftString;
  6.   dm.qry.Params[ 0 ].Size := 64;
  7.   dm.qry.Params[ 0 ].IsCaseSensitive := false;
  8.   dm.qry.Prepare;
  9.   dm.qry.Active := true;
  10.   k      := 0;
  11.   with dm.qry do
  12.     for i := 1 to 50000 do
  13.       begin
  14.       Params[ 0 ].AsString := 'oxymoron';
  15.       Refresh;
  16.       if not eof then
  17.         Inc( k );
  18.       Params[ 0 ].AsString := 'query';
  19.       Refresh;
  20. ..
  21.       Params[ 0 ].AsString := 'current_timestamp';
  22.       Refresh;
  23.       if not eof then
  24.         Inc( k );
  25.       end;
  26.   dm.qry.Active := False;
  27. stw.Stop;
  28. iMilisec := stw.ElapsedMilliseconds;     // 9 713 vs 28900
  29.  

Offline Miroslav Baláž

  • Plnoletý
  • ***
  • Příspěvků: 119
  • Karma: 4
    • Verze Delphi: D1,2,3,4,7,2005,2009, XE8,S,B,T10.2.2 Pro
Jinak samozrejme bude hledani indexovaneho sloupce rychlejsi nez bez nej. K tomu index existuje. Ale hledani bude pomalejsi nez nativni kolekce (index bude totiz zase jen hash kolekce).
No namatkou som robil pokusy aj s indexami:
  • Keď už som pri FB, tak najprv toto: PRIMARY KEY a UNIQUE sa vzájomne vylučujú. Čas sa líši medzi nimi len minimálne
  • Podobný efekt, že PRIMARY KEY a UNIQUE, sú výkonovo takmer identické, bol aj u SQLite
  • U SQLite: ak som dal len index a ten nebol ani UNIQUE ani PRIMARY KEY, tak jeho efekt bol veľmi slabý
  • Stojí za povšimnutie, že pracujem s ASCII 128 a case sensitive


Online Delfin

  • Guru
  • *****
  • Příspěvků: 546
  • Karma: 26
  • SW konzultant
    • Verze Delphi: 2009, Tokyo
Jinak samozrejme bude hledani indexovaneho sloupce rychlejsi nez bez nej. K tomu index existuje. Ale hledani bude pomalejsi nez nativni kolekce (index bude totiz zase jen hash kolekce).
No namatkou som robil pokusy aj s indexami:
  • Keď už som pri FB, tak najprv toto: PRIMARY KEY a UNIQUE sa vzájomne vylučujú. Čas sa líši medzi nimi len minimálne
  • Podobný efekt, že PRIMARY KEY a UNIQUE, sú výkonovo takmer identické, bol aj u SQLite
  • U SQLite: ak som dal len index a ten nebol ani UNIQUE ani PRIMARY KEY, tak jeho efekt bol veľmi slabý
  • Stojí za povšimnutie, že pracujem s ASCII 128 a case sensitive

Tady bych nez pokusy zvazil si o tematech neco precist ;)

- je jedno jaky DBMS; primarni klic je unikatni identifikator, proto je pro SQL nesmysl si vyptavat unikatnost podruhe
- protoze jsou oba indexy vnitrne hash kolekcemi
- protoze nema hash kolekci (teoreticky by mohl, s ukazateli na skupinu zaznamu)
- tomu nerozumim ::) :) (ale napr. muj oblibeny DBMS umoznuje vytvorit i "case insensitive" index - ale i fulltext search a dalsi)
« Poslední změna: 17-12-2017, 01:49:04 od Delfin »
Shiny disco balls! I don't like :)

Offline Miroslav Baláž

  • Plnoletý
  • ***
  • Příspěvků: 119
  • Karma: 4
    • Verze Delphi: D1,2,3,4,7,2005,2009, XE8,S,B,T10.2.2 Pro
    • Stojí za povšimnutie, že pracujem s ASCII 128 a case sensitive

    - tomu nerozumim ::) :)
    Pracujem so slovami, ktoré môžu obsahovať iba znaky #32 až max 'z' a z toho je výnimka oblasť 'A'..'Z'.
    Tak napríklad StringList má v tomto prípade smolu, že je case Insenzitive
    A naopak HashedStringList je zrejme tiež case insensitive a pritom dosahuje skvelý čas.

    Online Delfin

    • Guru
    • *****
    • Příspěvků: 546
    • Karma: 26
    • SW konzultant
      • Verze Delphi: 2009, Tokyo
    Pracujem so slovami, ktoré môžu obsahovať iba znaky #32 až max 'z' a z toho je výnimka oblasť 'A'..'Z'.
    Tak napríklad StringList má v tomto prípade smolu, že je case Insenzitive
    A naopak HashedStringList je zrejme tiež case insensitive a pritom dosahuje skvelý čas.

    Case insensitive hash list si muzes vytvorit jednoduse tak, ze vsechna slova prevedes na upper nebo lower case a pri hashovani klice udelas to same. Zadna slozitost. A string list nema az tak smulu, mozna jsi k nemu jen "nefer". Proto jsem chtel videt testovaci aplikaci ;)

    Bohuzel ani ted netusim kolik polozek je v kolekcich ani jak dlouhy je klic. To jsou podstatne informace pro benchmark.
    « Poslední změna: 17-12-2017, 02:14:25 od Delfin »
    Shiny disco balls! I don't like :)

    Offline Miroslav Baláž

    • Plnoletý
    • ***
    • Příspěvků: 119
    • Karma: 4
      • Verze Delphi: D1,2,3,4,7,2005,2009, XE8,S,B,T10.2.2 Pro
    V tomto príspevku, keď sa naňho riadne pozrieš, je komplet info.
    Pre zaujímavosť prikladám aj test pre FIREBIRD 3.0 EMBEDED
    Čas bol poslabší cca 29 000 milisekúnd.
    Kód: MySQL [Vybrat]
    1. CREATE TABLE sumar ( wordItem varchar( 64 ) NOT NULL primary key, eCategSet BIGINT, eFnFlagSet INTEGER );
    Kód som nevedel lepšie než takto:
    Kód: Delphi [Vybrat]
    1.   stw.Reset;
    2.   stw.Start;
    3.   dm.qry.Params.Clear;
    4.   dm.qry.SQL.Text := 'select eCategSet, eFnFlagSet from sumar where wordItem = ?';
    5.   dm.qry.Params[ 0 ].DataType := ftString;
    6.   dm.qry.Params[ 0 ].Size := 64;
    7.   dm.qry.Params[ 0 ].IsCaseSensitive := false;
    8.   dm.qry.Prepare;
    9.   k := 0;
    10.   with dm.qry do
    11.     for i := 1 to 50000 do
    12.       begin
    13.       Params[ 0 ].AsString := 'oxymoron';
    14.       Active := true;
    15.       if not eof then
    16.         Inc( k );
    17.       Active := False;
    18. ..  // Dalsie slova. Natvrdo nakodovane, tak ako ten oxymoron. Zoznam je nizsie
    19.       end;
    20.  
    21.   stw.Stop;
    22.   imilisec := stw.ElapsedMilliseconds;     // 28900
    Hľadalo sa v cykle týchto 7 slov :
    'oxymoron','query','abcd','#endwhile','date','vba_bitwise','current_timestamp'
    Cyklus bol:
    For i = 1  to 50 000
    Dictionary/resp. Tabulka, obsahuje celkom 221 slov.
    Mam sice testovaci program, ale je to kopia mojho hlavneho programu (90%) a Benchmark je zbytok.
    Zatiaľ je taký stav, že vyňatie všetkých testov by mi trvalo veľmi dlho.

    Offline Miroslav Baláž

    • Plnoletý
    • ***
    • Příspěvků: 119
    • Karma: 4
      • Verze Delphi: D1,2,3,4,7,2005,2009, XE8,S,B,T10.2.2 Pro
    Doplnená tabuľka výsledkov
    Možno prihodím ešte Access cez ActiveX ADO.
    Tak nejako tuším, že nebude na tom zrovna zle.
    Inak Access cez ODBC, čo teraz presadzuje Microsft je hrôza.
    20 rokov som používal ADO. Nech sa spamätajú a nech nemenia, čo je dobré
    « Poslední změna: 17-12-2017, 02:57:07 od mibainfo »

    Online Delfin

    • Guru
    • *****
    • Příspěvků: 546
    • Karma: 26
    • SW konzultant
      • Verze Delphi: 2009, Tokyo
    V tomto príspevku, keď sa naňho riadne pozrieš, je komplet info.

    Zkousel jsem ale neni. Muzu z nej vycist ze pouzivas 64 znakovy ANSI string jako klic (coz muze byt nefer vzhledem k Unicode hashovani v Delphi) a vzorek 50k opakovani. Delka klicu je neznama - vime o klici "oxymoron" (8 znaku). Kolik zaznamu je v kolekci (nebo tabulce) se zjistit neda.
    « Poslední změna: 17-12-2017, 03:03:28 od Delfin »
    Shiny disco balls! I don't like :)

    Online Delfin

    • Guru
    • *****
    • Příspěvků: 546
    • Karma: 26
    • SW konzultant
      • Verze Delphi: 2009, Tokyo
    Doplnená tabuľka výsledkov
    Možno prihodím ešte Access cez ActiveX ADO.
    Tak nejako tuším, že nebude na tom zrovna zle.
    Inak Access cez ODBC, čo teraz presadzuje Microsft je hrôza.
    20 rokov som používal ADO. Nech sa spamätajú a nech nemenia, čo je dobré

    Vzpamatuji? ADO je postavene na OLE DB jehoz naslednikem je ODBC. Vzhledem k poctu implementaci by IMHO ani pres snahu Microsoftu OLE DB vzkrisit melo radeji v 21. stoleti ze sveta odejit. Microsoft ve svych OS podporuje stare API s tim ze nabizi i nove alternativy, coz je super (spousta novych vznikla - a nektere jsou opravdu zajimave a Delphi je [zatim] neimplementuje). Tohle je odvetvi ktere sleduju s kazdym novym SDK (resim totiz konzultace vicemene vyhradne pro Windows; MSVC a Delphi co se tyce jazyku).
    « Poslední změna: 17-12-2017, 03:21:53 od Delfin »
    Shiny disco balls! I don't like :)

    Online Delfin

    • Guru
    • *****
    • Příspěvků: 546
    • Karma: 26
    • SW konzultant
      • Verze Delphi: 2009, Tokyo
    20 rokov som používal ADO. Nech sa spamätajú a nech nemenia, čo je dobré

    Navic ta veta je bohuzel dost nostalgicka (ale to mi prijde tak nejak cele toto forum; prosim jen neberte tento muj nazor osobne :) - jde o nazory, v zadnem pripade ne o vek!). Prijde mi to jako rict, 20 roku jezdim Favoritem, vyrabejte ho dal. U programovani je nostalgie o to horsi (byt se i ten Favorit da "udrzet na ceste"). Vidim to i u mnoha klientu kteri se me snazi presvedcit ze se jejich mnoha-set-formova aplikace neda zjednodusit. Da, a kolikrat se pak biji do hlavy ze se na ne programator vykaslal a oni mu za ty hodiny psani opakovaneho kodu tolik zaplatili. Na to jim odpovidam, navrhove sablony vznikly velice davno a slo jen o nezkusenost programatora - a nelzu, ty zakladni existuji velmi dlouho, jen je treba se kolikrat pred psanim kodu zamyslet nad tim co muze byt spolecne. Vic kodu neni vic Adidas :)

    Z praxe, jako prvni u klientu kteri chteji rozsahle upravy jednodussi Delphi aplikaci radim "jste schopni ji prevest do jineho jazyka"? Nebo ty co me kontaktuji s tim ze je jejich >30GB (nejmenovana) databaze "pomala" ocastuju po profilovani dotazem, "jste schopni prejit na jiny DBMS"? A spousta dalsich veci. Chystam Delphi blog se spoustou informaci z praxe, nejen ceskeho programovani (kvuli casu a dostupnosti asi jen v anglictine). Pak kdyztak muzu poslat odkaz...
    « Poslední změna: 17-12-2017, 04:34:50 od Delfin »
    Shiny disco balls! I don't like :)

    Offline pf1957

    • Padawan
    • ******
    • Příspěvků: 1966
    • Karma: 101
      • Verze Delphi: D2007, XE3, DX10
    Kolik zaznamu je v kolekci (nebo tabulce) se zjistit neda.
    221. Bylo to uvedeno nekolikrat

    Offline pf1957

    • Padawan
    • ******
    • Příspěvků: 1966
    • Karma: 101
      • Verze Delphi: D2007, XE3, DX10
    vime o klici "oxymoron" (8 znaku).
    Taky to tu uz bylo: 'oxymoron','query','abcd','#endwhile','date','vba_bitwise','current_timestamp'

    I kdyz uznavam, ze srozumitelnost prispevku od MB je nedobra - jsou prilis rozvlekle a nestrukturovane, takze ja je spis vnimam, nez bych je cetl, nicmene po 10 prispevcich nakonec v hlave zustane stopa, ze to tu nekde probehlo :-)
    « Poslední změna: 17-12-2017, 10:06:56 od pf1957 »

    Offline pf1957

    • Padawan
    • ******
    • Příspěvků: 1966
    • Karma: 101
      • Verze Delphi: D2007, XE3, DX10
    Tak napríklad StringList má v tomto prípade smolu, že je case Insenzitive
    No a je nejaky problem tu citlivost zapnout?

    Offline pf1957

    • Padawan
    • ******
    • Příspěvků: 1966
    • Karma: 101
      • Verze Delphi: D2007, XE3, DX10
      • Stojí za povšimnutie, že pracujem s ASCII 128
      Tomu se rika ASCII-7 nebo US-ASCII

      Offline pf1957

      • Padawan
      • ******
      • Příspěvků: 1966
      • Karma: 101
        • Verze Delphi: D2007, XE3, DX10
      Excellent
      Rated 1 time
      Zajimave. Jen se v tom nejak nedokazu zorientovat. Kolik tedy bylo polozek v kolekcich a jak dlouhy klic? Mohli bychom ziskat ke stazeni testovaci aplikaci?
      Me zarazel ten propastny rozdil mezi Dictionary a StringListem, tak jsem si tu rychle nastrikal consolovku (teda byl to porod, ja uz ten Delphi vubec neumim a vsechno jsem musel hledat ve wiki), ktera takovy test dokaze zopakovat a musim rict, ze jsem se dostal ke stejnym vysledkum, coz me neprestava udivovat: jestli dobre pocitam, tak tech namerenych 30+ ms u Dictionary predstavuje ~ 80 ns (!) per fetch :O

      Tady je ta consolovka, pokud si s tim chces hrat ;-)
      Kód: Delphi [Vybrat]
      1. program Project3;
      2.  
      3. {$APPTYPE CONSOLE}
      4.  
      5.  
      6. {$R *.res}
      7.  
      8. uses
      9.   System.SysUtils, System.Classes, System.Generics.Collections,
      10.   System.Diagnostics;
      11.  
      12. type
      13.   TPrepareProcedure = procedure(AData:TStringList);
      14.   TTestProcedure = procedure(APatterns:TStringList);
      15.  
      16. const
      17.   TestPasses = 50000;
      18.  
      19.   LoremIpsum =
      20.     'Lorem ipsum dolor sit amet consectetuer at ut vitae Suspendisse sagittis.'+
      21.     'A mauris ut ante elit vel congue platea sit convallis quam.'+
      22.     'Cursus sed mollis Pellentesque nec auctor Lorem sapien risus nulla sodales.'+
      23.     'Lorem eu pellentesque ac hac mollis elit Sed accumsan orci at.'+
      24.     'Urna lorem dictumst ante Vivamus massa elit ac elit nulla tempor.'+
      25.     'Dolor magna Vestibulum quis id.'+
      26.     'Dis tristique sed elit tincidunt nulla eget mauris Curabitur eu in.'+
      27.     'In ac Aenean eros Aenean at nec Nam iaculis Praesent enim.'+
      28.     'Orci non enim ligula auctor id scelerisque ligula convallis pellentesque justo.'+
      29.     'Ipsum interdum magna lorem pellentesque natoque sed semper eu eleifend Curabitur.'+
      30.     'Metus Phasellus malesuada nibh rhoncus scelerisque mauris ut Sed nec ac.'+
      31.     'Penatibus Nulla Vestibulum et ullamcorper ligula metus egestas a consequat.'+
      32.     'Rhoncus feugiat Nullam justo nibh Nam sit orci id Vestibulum nibh.'+
      33.     'Urna Aliquam Nulla Vivamus ligula nunc Curabitur fringilla pellentesque natoque Aenean.'+
      34.     'Leo Suspendisse faucibus nibh nibh egestas ornare condimentum elit condimentum commodo.'+
      35.     'Et dui et Nam Morbi tortor metus accumsan dui wisi suscipit.'+
      36.     'Ac wisi Curabitur at id sagittis Pellentesque Vestibulum ut a nunc.'+
      37.     'A nibh elit consequat dui.'+
      38.     'Id arcu purus lacus libero quam Mauris ac et ante elit.'+
      39.     'Sed magnis nisl ipsum Curabitur pede suscipit pellentesque sollicitudin wisi mauris.'+
      40.     'Urna neque eu lacinia netus enim senectus dolor convallis Proin tortor.'+
      41.     'Laoreet id Ut quis lacus Nullam Curabitur Integer volutpat Nullam pulvinar.'+
      42.     'Odio justo lacinia id a Morbi Vivamus Donec Vivamus volutpat Lorem. Nullam Curabitur a id a.'+
      43.     'Lorem ipsum dolor sit amet consectetuer elit Cum orci Quisque parturient.'+
      44.     'Laoreet neque Curabitur leo Phasellus tortor sem volutpat rhoncus tincidunt hendrerit.'+
      45.     'Magnis nunc vel nec tellus facilisi Vestibulum metus quis Quisque Vestibulum.'+
      46.     'Ligula commodo Aenean hendrerit et et sapien nisl rutrum lorem ipsum.'+
      47.     'Vestibulum pellentesque felis congue eu id nunc malesuada augue.'+
      48.     'Suspendisse commodo interdum Nam justo libero felis mus vel id vitae.'+
      49.     'Mattis accumsan Maecenas habitant Curabitur tincidunt rutrum Nunc Nulla lobortis quis.'+
      50.     'Semper ullamcorper Donec leo Nulla sem In ut convallis pharetra eu.'+
      51.     'Est commodo enim est Maecenas nibh Lorem Integer consequat purus Donec.'+
      52.     'Eu nunc vel orci Sed rhoncus leo et Nam ipsum id. Magna et.'+
      53.     'Dapibus felis Pellentesque gravida vestibulum convallis ut auctor quis tortor lorem.'+
      54.     'Interdum lacinia turpis pharetra consequat ligula Sed tincidunt id sed ut.'+
      55.     'Proin sem nulla mollis elit ut Nam Nulla tellus orci wisi.'+
      56.     'Pellentesque enim tristique at ante scelerisque tincidunt consequat Aenean justo tincidunt.'+
      57.     'Donec In ac metus justo risus Nunc hendrerit libero augue.'+
      58.     'Velit elit sed lorem consequat vel Nam a pellentesque interdum Curabitur.'+
      59.     'Nam habitasse quam Nam Pellentesque Curabitur ultrices nunc enim et felis.'+
      60.     'Id Vestibulum enim tellus semper Suspendisse hendrerit eget libero at nec.'+
      61.     'Adipiscing Vivamus id tortor fermentum id a in nulla libero eget.'+
      62.     'Condimentum urna euismod cursus ut elit enim laoreet Aliquam sem tellus.'+
      63.     'Morbi pretium pellentesque rhoncus sem Donec adipiscing cursus molestie dapibus tellus. Pede.'+
      64.     'Nunc Lorem Morbi nulla facilisi felis ac eros justo neque Sed.'+
      65.     'Ut Pellentesque eu Phasellus tempor et semper vitae faucibus vitae quis.'+
      66.     'Pulvinar quis est neque nec quis eget nunc massa Morbi quis.'+
      67.     'Nullam elit urna Ut nisl adipiscing Aliquam malesuada nunc tincidunt condimentum. Condimentum metus habitant at urna In.'+
      68.     'Ut nulla elit et nunc elit dui odio condimentum tempus ornare.'+
      69.     'Feugiat Phasellus Vestibulum vel consectetuer semper metus lobortis Nulla habitant accumsan.'+
      70.     'Elit Curabitur Sed Cum libero lobortis et Maecenas commodo neque condimentum.'+
      71.     'Aliquet montes consequat ipsum Donec et libero magnis gravida Suspendisse accumsan.'+
      72.     'Habitant et metus sociis hac cursus risus lorem ridiculus purus interdum.'+
      73.     'Aenean consectetuer at tincidunt orci urna enim gravida sit sem.'+
      74.     'Porta tellus Vivamus dui odio sit condimentum et laoreet rutrum facilisis.'+
      75.     'Fames Nunc semper Vivamus facilisis ligula urna sapien vitae fringilla auctor.'+
      76.     'Gravida ac morbi mattis consectetuer nunc pede sapien dignissim Sed consequat.'+
      77.     'Lobortis at mauris Nam feugiat id metus tempor risus sed ligula. Enim justo nec at Aliquam at.'+
      78.     'Dui Sed faucibus Phasellus nec elit vitae quam tortor porttitor adipiscing.'+
      79.     'Pellentesque ut sociis vel nec volutpat et nulla Nulla ac leo.'+
      80.     'Fringilla Duis Nulla urna fringilla nibh dolor cursus id dis nulla.'+
      81.     'Pellentesque amet pellentesque in id penatibus sed justo pretium ultrices Aliquam.'+
      82.     'Id lacus molestie justo montes odio a accumsan purus ante sem. Porta.';
      83.  
      84.  
      85. const
      86.   SearchPattern = 'oxymoron query abcd #endwhile date vba_bitwise current_timestamp';
      87.  
      88. var
      89.   TestData: TStringList;
      90.   TestPattern: TStringList;
      91.  
      92.   TestStringList: TStringList;
      93.   TestDictionary: TDictionary<string, TObject>;
      94.  
      95.  
      96.  
      97.   procedure PrepareTestData(AText:string; APattern:string);
      98.   var
      99.     i: integer;
      100.     ii: integer;
      101.     data: string;
      102.     TmpStringList: TStringList;
      103.   begin
      104.     TmpStringList := TStringList.Create();
      105.     TmpStringList.Delimiter := ' ';
      106.     TmpStringList.DelimitedText := AText;
      107.     for i := TmpStringList.Count-1 downto 0 do
      108.       if (TmpStringList[i].Trim()='') then
      109.         TmpStringList.Delete(i);
      110.  
      111.     TestData := TStringList.Create();
      112.     TestData.Sorted := true;
      113.     for i := 0 to TmpStringList.Count-1 do
      114.       begin
      115.         data := TmpStringList[i];
      116.         if TestData.IndexOf(data)<0 then
      117.           TestData.Add(data);
      118.       end;
      119.  
      120.     TestPattern := TStringList.Create();
      121.     TestPattern.Delimiter := ' ';
      122.     TestPattern.DelimitedText := APattern;
      123.  
      124.     TestData.Sorted := false;
      125.     for i:=0 to TestPattern.Count-1 do
      126.       begin
      127.         ii := Random(TestData.Count);
      128.         TestData.Insert(ii,TestPattern[i]);
      129.       end;
      130.     TestData.Sorted := true;
      131.   end;
      132.  
      133.   procedure StringListPrepareProcedure(AData:TStringList);
      134.   begin
      135.     TestStringList := TStringList.Create;
      136.     TestStringList.Assign(AData);
      137.     TestStringList.CaseSensitive := true;
      138.     TestStringList.Sorted := true;
      139.   end;
      140.  
      141.   procedure StringListTestProcedure(APatterns:TStringList);
      142.   var
      143.     i: integer;
      144.     FoundIdx: integer;
      145.     o: TObject;
      146.   begin
      147.     for i:=0 to APatterns.Count-1 do
      148.       begin
      149.         FoundIdx := TeststringList.IndexOf(APatterns[i]);
      150.         if (FoundIdx>=0) then
      151.           o := TestStringList.Objects[FoundIdx];
      152.       end;
      153.   end;
      154.  
      155.   procedure DictionaryPrepareProcedure(AData:TStringList);
      156.   var
      157.     key: string;
      158.   begin
      159.     TestDictionary := TDictionary<string, TObject>.Create();
      160.     for key in AData do
      161.       TestDictionary.Add(key, nil);
      162.   end;
      163.  
      164.   procedure DictionaryTestProcedure(APatterns:TStringList);
      165.   var
      166.     i: integer;
      167.     o: TObject;
      168.   begin
      169.     for i:=0 to APatterns.Count-1 do
      170.       begin
      171.         if TestDictionary.TryGetValue(APatterns[i], o) then
      172.           ;
      173.       end;
      174.   end;
      175.  
      176.   function PerformTest(APrepareProcedure: TPrepareProcedure; ATestProcedure:TTestProcedure): integer;
      177.   var
      178.     PassCount: integer;
      179.     stw: TStopWatch;
      180.   begin
      181.  
      182.     APrepareProcedure(TestData);
      183.  
      184.     stw := TStopWatch.StartNew;
      185.     for PassCount := 1 to TestPasses do
      186.       begin
      187.         ATestProcedure(TestPattern);
      188.       end;
      189.     stw.Stop;
      190.  
      191.     result := stw.ElapsedMilliseconds;
      192.  
      193.   end;
      194.  
      195. var
      196.   StringListTime: integer;
      197.   DictionaryTime: integer;
      198.  
      199. begin
      200.   try
      201.     randomize();
      202.     PrepareTestData(LoremIpsum, SearchPattern);
      203.  
      204.     writeln('Test #1');
      205.     StringListTime := PerformTest(StringListPrepareProcedure, StringListTestProcedure);
      206.     DictionaryTime := PerformTest(DictionaryPrepareProcedure, DictionaryTestProcedure);
      207.     writeln(Format('StringList: %d:5 ms',[StringListTime]));
      208.     writeln(Format('Dictionary: %d:5 ms',[DictionaryTime]));
      209.  
      210.     writeln('Test #2');
      211.     StringListTime := PerformTest(StringListPrepareProcedure, StringListTestProcedure);
      212.     DictionaryTime := PerformTest(DictionaryPrepareProcedure, DictionaryTestProcedure);
      213.     writeln(Format('StringList: %d:5 ms',[StringListTime]));
      214.     writeln(Format('Dictionary: %d:5 ms',[DictionaryTime]));
      215.  
      216.     writeln('Test #3');
      217.     StringListTime := PerformTest(StringListPrepareProcedure, StringListTestProcedure);
      218.     DictionaryTime := PerformTest(DictionaryPrepareProcedure, DictionaryTestProcedure);
      219.     writeln(Format('StringList: %d:5 ms',[StringListTime]));
      220.     writeln(Format('Dictionary: %d:5 ms',[DictionaryTime]));
      221.  
      222.  
      223.     Writeln('Pres Enter...');
      224.     Readln;
      225.   except
      226.     on E: Exception do
      227.       Writeln(E.ClassName, ': ', E.Message);
      228.   end;
      229. end.
      230.  
      231.  
      « Poslední změna: 17-12-2017, 11:44:08 od pf1957 »

      Offline Miroslav Baláž

      • Plnoletý
      • ***
      • Příspěvků: 119
      • Karma: 4
        • Verze Delphi: D1,2,3,4,7,2005,2009, XE8,S,B,T10.2.2 Pro
      Delfin, v niektorých veciach sa asi mýliš.
      1. Takto som začínal: 1 kB, potom 48, 640 kB bol zazrak. Disky podobne. Preto kod optimalizujem. Iba do jednorazovky neinvestujem zbytocny cas. Takze copy paste. Hlavne v noci
      2. ODBC bolo pred ADO, MS programatorov na ADO znasilnil. Potom, ked uz sa s tym zrovnali, zavrhol ho. A ano ADO je lepsie ako ODBC. V case ked ODBC nevedelo s cz/sk a pod. či datumy, tak ADO bežalo skvele. A bolo rýchle. Mnohé veci ešte MS nestihol do DOBC preniesť (typický MS. Nedorobky.). Takže zase sa začína od začiatku
      3. Niekde na webe som čítal vyjadrenie FireDAC, že áno sme pomalší na Access než ADO, pretože ODBC.
      4. DAO engina pre Access je ešte 2x tak rýchla ako ADO. A tie možnosti.. ODBC sa o nich nesníva. Pridobre to poznám. Samozrejme, mám slabiny ASCII-7 či US-ASCII, 1000-krát som to videl, len o tretej ráno už nevládzem. Tak som myslel, že tú moju interpretáciu pochopíte. (pf1957)
      5. Verím, že by som sa od Delfina mohol veľa naučiť, ale aj opačne, by bolo možné. Máme hodne iné ciele. To je všetko. Vedeli by sme sa dopĺňať. Dokážem však uvažovať aj samostane Za pomoci SO  :) .
      6.  ASCII-7 je výhodou, pretože pôjde výhradne o hľadanie názvov funkcií. Ak treba, viem si dict upraviť na plný unicode. Napr. pre vlastný export z Excelu na úrovni jeho interných xml-iek. Mám ho už 2 roky.
      To bola iná káva.
      « Poslední změna: 17-12-2017, 13:02:02 od mibainfo »

      Offline Miroslav Baláž

      • Plnoletý
      • ***
      • Příspěvků: 119
      • Karma: 4
        • Verze Delphi: D1,2,3,4,7,2005,2009, XE8,S,B,T10.2.2 Pro
      V tomto príspevku, keď sa naňho riadne pozrieš, je komplet info.

      Zkousel jsem ale neni. Muzu z nej vycist ze pouzivas 64 znakovy ANSI string jako klic (coz muze byt nefer vzhledem k Unicode hashovani v Delphi) a vzorek 50k opakovani. Delka klicu je neznama - vime o klici "oxymoron" (8 znaku). Kolik zaznamu je v kolekci (nebo tabulce) se zjistit neda.
      Obrazok tabulky je v prilohe.
      Ako konkretnu vzorku si mozes zobrat kludne rezervovane slova SQLite
      Hladane slova boli tieto:
      'oxymoron','query','abcd','#endwhile','date','vba_bitwise','current_timestamp'
      Nahodne cisla sa daju nagenerovat v Exceli. Tie moje sa pocitaju zlozitym sposobom z mnohych tabuliek v Exceli. Testovanie som k tomu len prilepil. Mam to v kopii originalu projektu.
      Nehovorim, ze toto porovnanie je obecne a ferove. Naopak, je to porovnanie presne pre moj pripad.
      Preto som sa tym zaoberal.
      Este mam jednu skusenost:
      z 350t vyhladavani vsetky moje testy vratia presne 150t nalezov (350t=7*50t). Niektore zo 7 slov sa v zozname nenachadzaju.
      Lenze FB tvrdosijne vracia 200t najdenych vyskytov. Ale uz s tym nechcem zabijat cas. Nie teraz.
      Este na zaver:
      - Nerobil som ziadne RANDOM a ani ine osetrenia. Proste sa opakuje vyhladavanie, bez ohladu, ci sa nieco kesuje, ci nie. Velmi podobne to bude aj v praxi pri mojom projekte, prenho je test na mieste.
      - Pre HashedStingList som nastavil CaseSensitive = true. Vysledok sa zlepsil o viac ako 10%. Nevedel som o tomto parametri, ze existuje.
      - Skusil som vzorovy program od pf1957. Je fakt, ze nieco celkom nesedi. Dictionary dava +-23 ms a StringList 434. V mojom projekte boli rozdiely vacsie. Ale dosledok je nepopieratelny - jasne vitazi Dictionary
      « Poslední změna: 17-12-2017, 16:53:36 od mibainfo »

      Offline pf1957

      • Padawan
      • ******
      • Příspěvků: 1966
      • Karma: 101
        • Verze Delphi: D2007, XE3, DX10

      - Skusil som vzorovy program od pf1957. Je fakt, ze nieco celkom nesedi. Dictionary dava +-23 ms a StringList 434. V mojom projekte boli rozdiely vacsie.
      Ty casy ~5 s pro string list mi to davalo pri nesetridenem string listu
      Citace
      Ale dosledok je nepopieratelny - jasne vitazi Dictionary
      Coz me osobne pri tak malem mnozstvi dat prekvapuje, hlavne o kolik. Kdybych delal v Delphi, talk bych to snad sel lustit :-)

      Offline Miroslav Baláž

      • Plnoletý
      • ***
      • Příspěvků: 119
      • Karma: 4
        • Verze Delphi: D1,2,3,4,7,2005,2009, XE8,S,B,T10.2.2 Pro
      - Skusil som vzorovy program od pf1957. Je fakt, ze nieco celkom nesedi. Dictionary dava +-23 ms a StringList 434. V mojom projekte boli rozdiely vacsie.
      Aha.. to mi vrtalo v hlave. Vcera vnoci som bol uz unaveny. Tento detail som nepodchytil vo svojej tabulke.
      Dik.
      PS
      Niekde vyssie som tvrdil, ze Dictionary som si upravil na unicode. Blbost. Na Case InSensitive. Lisiak Excel vacsinou pouziva InSensitive, ale interny slovnik ma na Sensitive. To aby tie texty zobrazoval tak, ako boli zapisane.. Naopak pre uzivatela, napr. vyhladavanie ma default Insensitive.
      « Poslední změna: 17-12-2017, 18:09:53 od mibainfo »

      Online Delfin

      • Guru
      • *****
      • Příspěvků: 546
      • Karma: 26
      • SW konzultant
        • Verze Delphi: 2009, Tokyo
      Delfin, v niektorých veciach sa asi mýliš.

      To je dost dobre mozne. Minimalne jsem se spletl v odhadu ze bude string list pro "maly" pocet polozek rychlejsi nez dictionary. Mile prekvapujici!
      A cile mame opravdu jine. O Excelu a Access vim snad jen tolik ze jsou u me jako zastupce v nabidce Start :)

      Tady je ta consolovka, pokud si s tim chces hrat ;-)

      Dekuju, zkusim! Byl jsem moc a moc liny ::) :)
      Shiny disco balls! I don't like :)

      Offline pf1957

      • Padawan
      • ******
      • Příspěvků: 1966
      • Karma: 101
        • Verze Delphi: D2007, XE3, DX10
      To je dost dobre mozne. Minimalne jsem se spletl v odhadu ze bude string list pro "maly" pocet polozek rychlejsi nez dictionary.
      Tak to jsme dva a rekl bych, ze to tak kdysi i byvalo. Na tu consolovku jsem vzal nejaky ten Berlin 10.1, co je zdarma a delat se v tom skoro neda, protoze D2007 mi nejde spustit, jelikoz mi nejaky update W10 nekam odpratal starou verzi .NET frameworku, ktery to vyzaduje :-(

      Offline Miroslav Baláž

      • Plnoletý
      • ***
      • Příspěvků: 119
      • Karma: 4
        • Verze Delphi: D1,2,3,4,7,2005,2009, XE8,S,B,T10.2.2 Pro
      Postreh:
      V mojom "benchmark"  na 350k vyhľadávaní: 15 ms
      Konzolovka pf1957 čas na 350k vyhľadávaní: 23 ms (1.5 x dlhšie)
      Tak už viem v čom je to. Som dosť prekvapený za tú veľkú réžiu cyklu (1-7).
      V konzolovke pf1957 som nahradil cyklus kódom rozpísaným natvrdo.
      Dôsledok: 
      Konzolovka pf1957 350k vyhľadávaní. Pôvodne  : 23 ms
      Konzolovka pf1957 350k vyhľadávaní. Rozpísané: 16 ms (čas takmer nachlp ako mojich 15 ms, viď začiatok témy)
      Réžia cyklu 1-7 spôsobuje 1,4 násobný rozdiel v čase!
      Pôvodný kód (takmer):
      Kód: Delphi [Vybrat]
      1.   for i:= 0 to APatterns.Count - 1  do
      2.     begin
      3.     if TestDictionary.TryGetValue( APatterns[ i ], classW ) then
      4.       Inc( k );
      5.     end;
      Rozpísané:
      Kód: Delphi [Vybrat]
      1.   if TestDictionary.TryGetValue( 'oxymoron', classW ) then
      2.      Inc( k );
      3.   if TestDictionary.TryGetValue( 'query', classW ) then
      4.      Inc( k );
      5.   if TestDictionary.TryGetValue( 'abcd', classW ) then
      6.      Inc( k );
      7.   if TestDictionary.TryGetValue( '#endwhile', classW ) then
      8.      Inc( k );
      9.   if TestDictionary.TryGetValue( 'date', classW ) then
      10.      Inc( k );
      11.   if TestDictionary.TryGetValue( 'vba_bitwise', classW ) then
      12.      Inc( k );
      13.   if TestDictionary.TryGetValue( 'current_timestamp', classW ) then
      14.      Inc( k );
      Navyše som sa pre istotu presvedčil, či TObject v dictionary u pf1957, nemá vplyv voči môjmu TClass. Potvrdené: o vs classW - žiadny rozdiel v čase. Použitý classW v konzolovke je rovnaký ako bol u mňa.


      Offline pf1957

      • Padawan
      • ******
      • Příspěvků: 1966
      • Karma: 101
        • Verze Delphi: D2007, XE3, DX10
      Réžia cyklu 1-7 spôsobuje 1,4 násobný rozdiel v čase!
      Nevim, jestli si uvedomujes, ze se jedna o (23-15 ms)/50000/7 = ~23 ns per cycle.

      Ve svetle toho me spis udivuje, jak dokaze vyndat zada z Dictionary za jen dvojnasobnou dobu tj. ~43 ns

      Offline Miroslav Baláž

      • Plnoletý
      • ***
      • Příspěvků: 119
      • Karma: 4
        • Verze Delphi: D1,2,3,4,7,2005,2009, XE8,S,B,T10.2.2 Pro
      Uprimne priznavam, ze ns su mimo moju rozlisovaciu schopnost :)

      Offline Miroslav Baláž

      • Plnoletý
      • ***
      • Příspěvků: 119
      • Karma: 4
        • Verze Delphi: D1,2,3,4,7,2005,2009, XE8,S,B,T10.2.2 Pro
      Excellent
      Rated 1 time
      Zhrnutie výsledkov je v priloženej tabuľke.
      Pre rýchly prehľad:
      • Dictionary jasne vyhral.
      • HashedStringList, je tiež dobrý. Nezáleží či je sortovaný, na rozdiel od bežného StringList
      • SQLite inMemory cez LowLevel poskytuje najmenej rovnako rýchle vyhľadávanie ako StringList.
      • SQLite inMemory vo verzii FDQuery výrazne zaostáva za LowLevel prístupom
      • SQLite, pokiaľ nie je inMemory, je inak veľmi citlivá na nastavenia v Connection
      • FireBird sa doťahuje na SQLite, pokiaľ nastavenia SQLite nie sú ideálne
      Pri LowLevel, mám na mysli prístup cez : FireDAC.Phys.SQLiteWrapper.pas

      Offline Miroslav Baláž

      • Plnoletý
      • ***
      • Příspěvků: 119
      • Karma: 4
        • Verze Delphi: D1,2,3,4,7,2005,2009, XE8,S,B,T10.2.2 Pro
      Réžia cyklu 1-7 spôsobuje 1,4 násobný rozdiel v čase!
      Nevim, jestli si uvedomujes, ze se jedna o (23-15 ms)/50000/7 = ~23 ns per cycle.

      Ve svetle toho me spis udivuje, jak dokaze vyndat zada z Dictionary za jen dvojnasobnou dobu tj. ~43 ns
      Dost vtipne to pride, ze ked od 15 ms odcitam reziu na cykly, ktora je tak okolo 7-8 ms, tak to "vyndat .." je hotove, za cas okolo 8 milisekund..
      Voci tomu so 400 ms stoja SQLite inMemory, alebo StringList..
      Teda prakticky najblizsi konkurenti su 50 x pomalsi. Tam je rezia cyklu zanedbatelna a casy sa od pokusu k pokusu menia o tých +-20 ms.
      Cas 15 ms pre Dictionary to dava na chlp stabilne. Aj ked to spustim hocikedy.
      Nie je v tom ani ziadny podvod, pretoze, stale vrati true 200 000x z celkovo 350 000 pokusov. Teda nie je to, ze by prebehol, len nejakym svindlom..
      A kazdy z tych 350k pokusov znamena ze sa prehliada 221 poloziek. A to cele za 8 ms aj s s ponuknutim prislusnej Value v Dictionary!
      « Poslední změna: 20-12-2017, 20:22:52 od mibainfo »

      Offline geby

      • Plnoletý
      • ***
      • Příspěvků: 168
      • Karma: 15
        • Verze Delphi: 7, 2007, XE2, 10.2
        • Synapse
      Excellent
      Rated 1 time
      Tak to jsme dva a rekl bych, ze to tak kdysi i byvalo. Na tu consolovku jsem vzal nejaky ten Berlin 10.1, co je zdarma a delat se v tom skoro neda, protoze D2007 mi nejde spustit, jelikoz mi nejaky update W10 nekam odpratal starou verzi .NET frameworku, ktery to vyzaduje :-(

      Zkus tohle: https://blog.dummzeuch.de/2013/11/10/delphi-2007-on-windows-8-1/ (Delam to po kazdem velkem updatu W10...)

      Offline pf1957

      • Padawan
      • ******
      • Příspěvků: 1966
      • Karma: 101
        • Verze Delphi: D2007, XE3, DX10
      Zkus tohle: https://blog.dummzeuch.de/2013/11/10/delphi-2007-on-windows-8-1/ (Delam to po kazdem velkem updatu W10...)
      Diky. Funguje.

      Ja uz jsem to jednou v minulosti taky musel hledat a kopirovat, ale narozdil od nej jsem to suse nakopiroval do C:\Windows\Microsoft.NET\Framework\v2.0.50727\ (protoze 64bitovy .NET ma samostatny adresar C:\Windows\Microsoft.NET\Framework64\)/

      Jen jsem nemel uz motivaci to zprovoznovat, tak jsi me trochu postouchnul :-)

       

      S rychlou odpovědí můžete používat BB kódy a emotikony jako v běžném okně pro odpověď, ale daleko rychleji.

      Jméno: E-mail:
      Ověření:
      Kolik je šest plus čtyři (slovem):