/// answer to http://stackoverflow.com/q/39685770/458259 program BinarySearchFastMultiInsert; { one million rows benchmark: INSERT 1000000 rows in 215.49ms SORT ARRAY 1000000 in 192.64ms SELECT 1000000 rows per Key index in 26.15ms ten million rows benchmark: INSERT 10000000 rows in 2.10s SORT ARRAY 10000000 in 3.06s SELECT 10000000 rows per Key index in 357.72ms compare to SQLite3 in-memory, with index created after insertion: INSERT 1000000 rows in 2.91s CREATE INDEX 1000000 in 1.28s SELECT 1000000 rows per Key index in 1.15s } {$APPTYPE CONSOLE} uses {$I SynDprUses.inc} // use FastMM4 on older Delphi, or set FPC threads SysUtils, SynCommons; type TEntry = record Key: RawUTF8; Value: RawUTF8; end; TEntryDynArray = array of TEntry; const // used to create some fake data, with some multiple occurences of Key COUNT = 1000000; // million rows insertion ! UNIQUE_KEY = 1024; // should be a power of two procedure Process; var entry: TEntryDynArray; entrycount: integer; entries: TDynArray; procedure DoInsert; var i: integer; rec: TEntry; begin for i := 0 to COUNT-1 do begin // here we fill with some data FormatUTF8('KEY%',[i and pred(UNIQUE_KEY)],rec.Key); FormatUTF8('VALUE%',[i],rec.Value); entries.Add(rec); end; end; procedure DoSelect; var i,j, first,last, total: integer; key: RawUTF8; begin total := 0; for i := 0 to pred(UNIQUE_KEY) do begin FormatUTF8('KEY%',[i],key); assert(entries.FindAllSorted(key,first,last)); for j := first to last do assert(entry[j].Key=key); inc(total,last-first+1); end; assert(total=COUNT); end; var timer: TPrecisionTimer; begin entries.InitSpecific(TypeInfo(TEntryDynArray),entry,djRawUTF8,@entrycount); write('INSERT ', COUNT, ' rows'); timer.Start; DoInsert; writeln(' in ',timer.Stop); write('SORT ARRAY ', COUNT); timer.Start; entries.Sort; // faster done after insertion writeln(' in ',timer.Stop); write('SELECT ', COUNT, ' rows per Key index'); timer.Start; DoSelect; writeln(' in ',timer.Stop); // exit; // comment this line to avoid binary and json serialization timer.Start; FileFromString(entries.SaveTo,'test.db'); FileFromString(entries.SaveToJson,'test.json'); writeln('SAVED in ',timer.Stop); end; begin TTextwriter.RegisterCustomJSONSerializerFromText( TypeInfo(TEntryDynArray),'key,value:RawUTF8'); Process; writeln('Press [Enter]'); readln; end.