• test2


    program Project2;
    
    {$APPTYPE CONSOLE}
    {$R *.res}
    
    uses
      windows, System.SysUtils;
    
    function memcmp(ptr1: PAnsiChar; ptr2: PAnsiChar; num: DWORD): Integer; cdecl;
      external 'Ntdll.dll' name 'memcmp';
    
    function sprintf(S: PAnsiChar; const Format: PAnsiChar): Integer; cdecl; varargs;
      external 'msvcrt.dll';
    
    function ZStartTime(var StartTime: Int64): Boolean;
    begin
      Result := QueryPerformanceCounter(StartTime);
    end;
    
    function ZStopTime(const StartTime: Int64): AnsiString;
    var
      iCounterPerSec, StopTime: Int64;
      time: Single;
    begin
      if QueryPerformanceCounter(StopTime) then
      begin
        if QueryPerformanceFrequency(iCounterPerSec) then
        begin
    
          time := (0 - StartTime + StopTime) / iCounterPerSec;
    
          Result := '';
          SetLength(Result, 25);
    
          SetLength(Result, sprintf(PAnsiChar(Result), 'Result: %f sec.', time));
        end
        else
          Result := 'Error[ZStopTime(QueryPerformanceFrequency)]';
      end
      else
        Result := 'Error[ZStopTime(QueryPerformanceCounter)]';
    end;
    
    function base64_encode(const str: string): string;
    const
      table: PWideChar = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
    type
      PArrayChars = ^TArrayChars;
      TArrayChars = array of char;
    var
      len, i, r: Integer;
      a, b: Byte;
      Sum: Cardinal;
    begin
      len := Length(str);
    
      SetLength(Result, ((len + 2) div 3) * 4);
    
      i := 0;
      r := 0;
      while i <= len - 3 do
      begin
        Sum := WORD(str[i + 1]) shl 16 + WORD(str[i + 2]) shl 8 + WORD(str[i + 3]);
    
        PArrayChars(@Result)^[r + 0] := table[Sum shr 18 and $3F];
        PArrayChars(@Result)^[r + 1] := table[Sum shr 12 and $3F];
        PArrayChars(@Result)^[r + 2] := table[Sum shr 6 and $3F];
        PArrayChars(@Result)^[r + 3] := table[Sum and $3F];
    
        inc(i, 3);
        inc(r, 4);
      end;
    
      case len mod 3 of
        1:
          begin
            a := WORD(str[len]) and $FF;
            PArrayChars(@Result)^[r + 0] := table[a SHR 2];
            PArrayChars(@Result)^[r + 1] := table[a and 3 SHL 4];
            PArrayChars(@Result)^[r + 2] := '=';
            PArrayChars(@Result)^[r + 3] := '=';
          end;
        2:
          begin
            a := WORD(str[i + 1]) and $FF;
            b := WORD(str[i + 2]) and $FF;
            PArrayChars(@Result)^[r + 0] := table[a SHR 2];
            PArrayChars(@Result)^[r + 1] := table[((a and 3) SHL 4) or (b SHR 4)];
            PArrayChars(@Result)^[r + 2] := table[b and $0F SHL 2];
            PArrayChars(@Result)^[r + 3] := '=';
          end;
      end;
    end;
    
    var
      i: Cardinal;
      StartTime: Int64;
    
    begin
      try
        Writeln(base64_encode('HytujkyHytujkyukHytujkyukuk'));
        if ZStartTime(StartTime) then
        begin
          for i := 0 to 10000000 do
          begin
            base64_encode('HytujkyHytujkyukHytujkyukuk');
          end;
          Writeln(ZStopTime(StartTime));
        end;
    
      except
        on E: Exception do
          Writeln(E.ClassName, ': ', E.Message);
      end;
      Readln;
    
    end.
    View Code
    function ELFHash(const Value: String): Integer;
    var
      i, x: Integer;
    begin
      Result := 0;
      for i := 1 to Length(Value) do
      begin
        Result := (Result shl 4) + Ord(Value[i]);
        x := Result and $F0000000;
        if (x <> 0) then
          Result := Result xor (x shr 24);
        Result := Result and (not x);
      end;
    end;
    
    program SpeedTest;
    
    {$APPTYPE CONSOLE}
    
    {$R *.res}
    
    uses
      Winapi.Windows,
      System.Generics.Defaults,
      System.Generics.Collections,
      System.SysUtils,
      System.Classes;
    
    type
      TStringEqualComparer = class(TInterfacedObject)
        function Equals(const Left, Right: string): Boolean; reintroduce;
        // важно! если сделать виртуальный метод - то скорость падает ~3 раза
        // function GetHashCode(const Value: string): Integer; reintroduce; virtual; abstract;
      end;
      TComparerClass = class of TStringEqualComparer;
    
      TSedgwicComparer = class(TStringEqualComparer, IEqualityComparer<string>)
        function GetHashCode(const Value: string): Integer; reintroduce;
      end;
    
      TShaPerfectComparer = class(TStringEqualComparer, IEqualityComparer<string>)
        function GetHashCode(const Value: string): Integer; reintroduce;
      end;
    
      TFastComparer = class(TStringEqualComparer, IEqualityComparer<string>)
        function GetHashCode(const Value: string): Integer; reintroduce;
      end;
    
    { TStringEqualComparer }
    
    function TStringEqualComparer.Equals(const Left, Right: string): Boolean;
    label
      cmp_ptrs;
    var
      i, Count: NativeInt;
      S1, S2: PNativeUInt;
    begin
      S1 := Pointer(Left);
      S2 := Pointer(Right);
      if (S1 <> S2) and (S1 <> nil) and (S2 <> nil) then
      begin
        Dec(NativeUInt(S1), SizeOf(Integer));
        Dec(NativeUInt(S2), SizeOf(Integer));
        Count := PInteger(S1)^;
        if (Integer(Count) <> PInteger(S2)^) then goto cmp_ptrs;
        Inc(NativeUInt(S1), SizeOf(Integer));
        Inc(NativeUInt(S2), SizeOf(Integer));
    
        for i := 1 to Count shr {$if SizeOf(NativeUInt) = 8}2{$else}1{$endif} do
        begin
          if (S1^ <> S2^) then goto cmp_ptrs;
          Inc(S1);
          Inc(S2);
        end;
    
        {$if SizeOf(NativeUInt) = 8}
        if (Count and 2 <> 0) then
        begin
          if (PCardinal(S1)^ <> PCardinal(S2)^) then goto cmp_ptrs;
          Inc(NativeUInt(S1), SizeOf(Cardinal));
          Inc(NativeUInt(S2), SizeOf(Cardinal));
        end;
        {$endif}
    
        if (PWord(S1)^ <> PWord(S2)^) then goto cmp_ptrs;
        Result := True;
        Exit;
      end else
      begin
      cmp_ptrs:
        Result := (S1 = S2);
      end;
    end;
    
    { TSedgwicComparer }
    
    function TSedgwicComparer.GetHashCode(const Value: string): Integer;
    var
      a, i: Integer;
    begin
      Result := 0;
      a := 63689;
      for i := 0 to Length(Value) - 1 do
      begin
        Result := Result * a + PWordArray(Value)[i];
        a := a * 378551;
      end;
    end;
    
    { TShaPerfectComparer }
    
    function TShaPerfectComparer.GetHashCode(const Value: string): Integer;
    var
      i, j: integer;
    begin;
      Result:=0;
      for i:=0 to Length(Value)-1 do begin;
        j:=ord(Value[i+1]);
        Result:=Result * 1041204193 + (j+1507220783);
        end;
      Result:=Result * -1866451833;
    end;
    
    { TFastComparer }
    
    function TFastComparer.GetHashCode(const Value: string): Integer;
    var
      i, X, Count: Integer;
      S: PByte;
    begin
      S := Pointer(Value);
      Result := 0;
      if (S <> nil) then
      begin
        Count := PInteger(NativeInt(Value) - 4)^;
    
        Result := Count;
        for i := 1 to (Count shr 1) do
        begin
          X := Result xor PInteger(S)^;
          Result := Result * i;
          Inc(Result, X shr 16);
          Inc(S, SizeOf(Integer));
          Inc(Result, X);
        end;
    
        Inc(Result, Ord(PChar(S)^));
        Result := Result * -1866451833;
      end;
    end;
    
    
    const
      ITERATIONS_COUNT = 100;
      COMPARERS: array[0..2] of TComparerClass = (TSedgwicComparer, TShaPerfectComparer, TFastComparer);
    
    var
      i, c, k: NativeInt;
      VALUES: TArray<string>;
      List: TStringList;
      Time: Cardinal;
      Comparer: IEqualityComparer<string>;
      Dictionary: TDictionary<string, Integer>;
    
    begin
      try
        // загрузка значений
        List := TStringList.Create;
        try
          List.LoadFromFile('StringBase.txt');
          SetLength(VALUES, List.Count);
    
          for i := 0 to List.Count - 1 do
          begin
            VALUES[i] := List[i];
          end;
        finally
          List.Free;
        end;
    
        // цикл по всем компарерам
        for c := Low(COMPARERS) to High(COMPARERS) do
        begin
          // компарер, конструктор
          Write(COMPARERS[c].ClassName, '...');
          case c of
            0: Comparer := TSedgwicComparer.Create;
            1: Comparer := TShaPerfectComparer.Create;
          else
            // 2:
            Comparer := TFastComparer.Create;
           end;
          Dictionary := TDictionary<string, Integer>.Create(Length(VALUES), Comparer);
    
          try
            // заполняем
            for k := Low(VALUES) to High(VALUES) do
              Dictionary.Add(VALUES[k], 0);
    
            // тестируем
            Time := GetTickCount;
            for i := 1 to ITERATIONS_COUNT do
            for k := Low(VALUES) to High(VALUES) do
            begin
              Dictionary.Items[VALUES[k]];
            end;
            Time := GetTickCount - Time;
            Writeln(' ', Time, 'мс');
    
          finally
            Comparer := nil;
            Dictionary.Free;
          end;
        end;
      except
        on E: Exception do
          Writeln(E.ClassName, ': ', E.Message);
      end;
    
      // нажать Enter
      Writeln;
      Write('Press Enter');
      Readln;
    end.
    
      1 program HashTest;
      2 
      3 {$APPTYPE CONSOLE}
      4 
      5 {$R *.res}
      6 
      7 uses
      8   Winapi.Windows,
      9   System.SysUtils,
     10   System.Classes,
     11   System.Generics.Collections,
     12   System.Generics.Defaults;
     13 
     14 type
     15   TStringEqualComparer = class(TInterfacedObject)
     16     function Equals(const Left, Right: string): Boolean; reintroduce;
     17     // важно! если сделать виртуальный метод - то скорость падает ~3 раза
     18     // function GetHashCode(const Value: string): Integer; reintroduce; virtual; abstract;
     19   end;
     20 
     21   TSedgwicComparer = class(TStringEqualComparer, IEqualityComparer<string>)
     22     function GetHashCode(const Value: string): Integer; reintroduce;
     23   end;
     24 
     25   TSimpleComparer = class(TStringEqualComparer, IEqualityComparer<string>)
     26     function GetHashCode(const Value: string): Integer; reintroduce;
     27   end;
     28 
     29   TShiftComparer = class(TStringEqualComparer, IEqualityComparer<string>)
     30     function GetHashCode(const Value: string): Integer; reintroduce;
     31   end;
     32 
     33   TFastComparer = class(TStringEqualComparer, IEqualityComparer<string>)
     34     function GetHashCode(const Value: string): Integer; reintroduce;
     35   end;
     36 
     37   TMurmur3Comparer = class(TStringEqualComparer, IEqualityComparer<string>)
     38     function GetHashCode(const Value: string): Integer; reintroduce;
     39   end;
     40 
     41 { TStringEqualComparer }
     42 
     43 function TStringEqualComparer.Equals(const Left, Right: string): Boolean;
     44 label
     45   cmp_ptrs;
     46 var
     47   i, Count: NativeInt;
     48   S1, S2: PNativeUInt;
     49 begin
     50   S1 := Pointer(Left);
     51   S2 := Pointer(Right);
     52   if (S1 <> S2) and (S1 <> nil) and (S2 <> nil) then
     53   begin
     54     Dec(NativeUInt(S1), SizeOf(Integer));
     55     Dec(NativeUInt(S2), SizeOf(Integer));
     56     Count := PInteger(S1)^;
     57     if (Integer(Count) <> PInteger(S2)^) then goto cmp_ptrs;
     58     Inc(NativeUInt(S1), SizeOf(Integer));
     59     Inc(NativeUInt(S2), SizeOf(Integer));
     60 
     61     for i := 1 to Count shr {$ifdef CPUX64}2{$else}1{$endif} do
     62     begin
     63       if (S1^ <> S2^) then goto cmp_ptrs;
     64       Inc(S1);
     65       Inc(S2);
     66     end;
     67 
     68     {$ifdef CPUX64}
     69     if (Count and 2 <> 0) then
     70     begin
     71       if (PCardinal(S1)^ <> PCardinal(S2)^) then goto cmp_ptrs;
     72       Inc(NativeUInt(S1), SizeOf(Cardinal));
     73       Inc(NativeUInt(S2), SizeOf(Cardinal));
     74     end;
     75     {$endif}
     76 
     77     if (PWord(S1)^ <> PWord(S2)^) then goto cmp_ptrs;
     78     Result := True;
     79     Exit;
     80   end else
     81   begin
     82   cmp_ptrs:
     83     Result := (S1 = S2);
     84   end;
     85 end;
     86 
     87 { TSedgwicComparer }
     88 
     89 function TSedgwicComparer.GetHashCode(const Value: string): Integer;
     90 var
     91   a, i: Integer;
     92 begin
     93   Result := 0;
     94   a := 63689;
     95   for i := 1 to Length(Value) - 1 do
     96   begin
     97     Result := Result * a + PWordArray(Value)[i];
     98     a := a * 378551;
     99   end;
    100 end;
    101 
    102 { TSimpleComparer }
    103 
    104 function TSimpleComparer.GetHashCode(const Value: string): Integer;
    105 var
    106   i: NativeInt;
    107   S: PChar;
    108 begin
    109   S := Pointer(Value);
    110   Result := 0;
    111   if (S <> nil) then
    112   begin
    113     Result := PInteger(NativeInt(Value) - 4)^;
    114 
    115     for i := 0 to NativeInt(Result) - 1 do
    116     begin
    117       Result := Result + Ord(S[i]);
    118     end;
    119   end;
    120 end;
    121 
    122 { TShiftComparer }
    123 
    124 function TShiftComparer.GetHashCode(const Value: string): Integer;
    125 var
    126   i: NativeInt;
    127   S: PChar;
    128 begin
    129   S := Pointer(Value);
    130   Result := 0;
    131   if (S <> nil) then
    132   begin
    133     Result := PInteger(NativeInt(Value) - 4)^;
    134 
    135     for i := 0 to NativeInt(Result) - 1 do
    136     begin
    137       Result := Result xor (Result shr (i and 7 + 1)) + Ord(S[i]);
    138     end;
    139   end;
    140 end;
    141 
    142 { TFastComparer }
    143 
    144 function TFastComparer.GetHashCode(const Value: string): Integer;
    145 var
    146   i, X, Count: Integer;
    147   S: PByte;
    148 begin
    149   S := Pointer(Value);
    150   Result := 0;
    151   if (S <> nil) then
    152   begin
    153     Count := PInteger(NativeInt(Value) - 4)^;
    154 
    155     Result := Count;
    156     for i := 1 to (Count shr (SizeOf(Char) xor 3)) do
    157     begin
    158       X := Result xor PInteger(S)^;
    159       Result := Result * i;
    160       Inc(Result, X shr 19);
    161       Inc(S, SizeOf(Integer));
    162       Inc(Result, X);
    163     end;
    164 
    165     for i := 1 to (Count and ((SizeOf(Char) xor 2) or 1)) do
    166     begin
    167       Result := Result * i;
    168       Inc(Result, Ord(PChar(S)^));
    169       Inc(S, SizeOf(Char));
    170     end;
    171   end;
    172 end;
    173 
    174 { TMurmur3Comparer }
    175 
    176 type
    177   uint32_t = cardinal;
    178 {$IFNDEF fpc}
    179 function RolDWord(x:uint32_t;r:integer):uint32_t;
    180 {$IF Defined(CPUX86)}
    181 asm
    182   MOV  CL, DL
    183   ROL  EAX, CL
    184 end;
    185 {$ELSEIF Defined(CPUX64)}
    186 asm
    187   MOV  EAX, ECX
    188   MOV  CL, DL
    189   ROL  EAX, CL
    190 end;
    191 {$ELSE}
    192 begin
    193   Result:=(x shl r) or (x shr (32 - r));
    194 end;
    195 {$IFEND}
    196 {$ENDIF}
    197 
    198 function MurmurHash3_x86_32 ( const Akey; len:uint32_t): cardinal;
    199 type
    200   Puint32_t=^uint32_t;
    201 
    202 var data:Puint32_t;
    203   nblocks,tail_len,i:uint32_t;
    204   h1,k1:uint32_t;
    205 const
    206    c1:uint32_t = $cc9e2d51;
    207    c2:uint32_t = $1b873593;
    208 type
    209  TTailRec=packed record
    210   case Integer of
    211    1:(b:byte);
    212    2:(w:word);
    213    3:(uint24_d:uint32_t);
    214  end;
    215 var
    216  tail:^TTailRec;
    217 begin
    218   data := @Akey;
    219   nblocks := len div 4;
    220 
    221   h1 := 0;
    222   //----------
    223   // body
    224   for i:=1 to nblocks do begin
    225     k1 := data^;
    226 
    227     k1 := k1 * c1;
    228     k1 := RolDWord(k1,15);
    229     k1 := k1*c2;
    230 
    231     h1 := h1 xor k1;
    232     h1 := RolDWord(h1,13);
    233     h1 := h1*5+$e6546b64;
    234 
    235     inc(data);
    236   end;
    237 
    238   //----------
    239   // tail
    240 
    241   tail :=pointer(data);
    242 
    243   k1 := 0;
    244   tail_len:=len and 3;
    245   if tail_len>0 then begin
    246     case tail_len of
    247     3: k1 :=k1 xor (tail^.uint24_d and $FFFFFF);
    248     2: k1 :=k1 xor tail^.w;
    249     1: k1 :=k1 xor tail^.b;
    250     end;
    251 
    252     k1 :=k1* c1;
    253     k1 := RolDWord(k1,15);
    254     k1 :=k1 * c2;
    255     h1 :=h1 xor k1;
    256   end;
    257   //----------
    258   // finalization
    259 
    260   h1 :=h1 xor len;
    261 
    262   //h1 := fmix32(h1);  Result := h1;
    263 
    264   h1 :=h1 xor (h1 shr 16);
    265   h1 :=h1* $85ebca6b;
    266   h1 :=h1 xor (h1 shr 13);
    267   h1 :=h1 * $c2b2ae35;
    268 
    269   Result:=h1 xor (h1 shr 16);
    270 end;
    271 function TMurmur3Comparer.GetHashCode(const Value: string): Integer;
    272 begin
    273   Result := Integer(MurmurHash3_x86_32(PChar(Value)^, Length(Value) * SizeOf(Char)));
    274 end;
    275 
    276 
    277 
    278 procedure TestDict(Title: string; L: TStringList; C: IEqualityComparer<string> = nil);
    279 var
    280   t1, t2: Cardinal;
    281   D: TDictionary<string, Integer>;
    282   i: Integer;
    283 begin
    284   Write(Title);
    285   //
    286   D := TDictionary<string, Integer>.Create(L.Count, C);
    287   try
    288    t1 := GetTickCount();
    289     for i := L.Count - 1 downto 0 do
    290       D.AddOrSetValue(L[i], i);
    291 
    292     t2 := GetTickCount();
    293     Writeln(t2 - t1);
    294   finally
    295     D.Free;
    296   end;
    297   //
    298 end;
    299 
    300 function GenStr(): string;
    301 var
    302   l: Integer;
    303 begin
    304   l := Random(1024);
    305   SetLength(Result, l);
    306   for l := l downto 1 do
    307   begin
    308     Result[l] := Char(Random(256));
    309   end;
    310 end;
    311 
    312 procedure GenList(L: TStringList);
    313 var
    314   i: Integer;
    315 begin
    316   RandSeed := 0;
    317   for i := 1 to 1000000 do
    318     L.Add(GenStr)
    319 end;
    320 
    321 var
    322   L: TStringList;
    323 
    324 begin
    325   try
    326     L:= TStringList.Create;
    327     try
    328       GenList(L);
    329       TestDict( 'std: ', L);
    330 
    331       TestDict( 'TSedgwicComparer: ', L, TSedgwicComparer.Create);
    332       TestDict( 'TMurmur3Comparer: ', L, TMurmur3Comparer.Create);
    333       TestDict( 'TFastComparer: ', L, TFastComparer.Create);
    334       TestDict( 'TShiftComparer: ', L, TShiftComparer.Create);
    335       TestDict( 'TSimpleComparer: ', L, TSimpleComparer.Create);
    336     finally
    337       L.Free;
    338     end;
    339     { TODO -oUser -cConsole Main : Insert code here }
    340   except
    341     on E: Exception do
    342       Writeln(E.ClassName, ': ', E.Message);
    343   end;
    344 end.
    View Code
    program SpeedTest;
    
    {$APPTYPE CONSOLE}
    
    {$R *.res}
    
    uses
      Winapi.Windows,
      System.Generics.Defaults,
      System.Generics.Collections,
      System.SysUtils,
      System.Classes;
    
    type
      TStringEqualComparer = class(TInterfacedObject)
        function Equals(const Left, Right: string): Boolean; reintroduce;
        // важно! если сделать виртуальный метод - то скорость падает ~3 раза
        // function GetHashCode(const Value: string): Integer; reintroduce; virtual; abstract;
      end;
      TComparerClass = class of TStringEqualComparer;
    
      TSedgwicComparer = class(TStringEqualComparer, IEqualityComparer<string>)
        function GetHashCode(const Value: string): Integer; reintroduce;
      end;
    
      TSimpleComparer = class(TStringEqualComparer, IEqualityComparer<string>)
        function GetHashCode(const Value: string): Integer; reintroduce;
      end;
    
      TShiftComparer = class(TStringEqualComparer, IEqualityComparer<string>)
        function GetHashCode(const Value: string): Integer; reintroduce;
      end;
    
      TFastComparer = class(TStringEqualComparer, IEqualityComparer<string>)
        function GetHashCode(const Value: string): Integer; reintroduce;
      end;
    
    { TStringEqualComparer }
    
    function TStringEqualComparer.Equals(const Left, Right: string): Boolean;
    label
      cmp_ptrs;
    var
      i, Count: NativeInt;
      S1, S2: PNativeUInt;
    begin
      S1 := Pointer(Left);
      S2 := Pointer(Right);
      if (S1 <> S2) and (S1 <> nil) and (S2 <> nil) then
      begin
        Dec(NativeUInt(S1), SizeOf(Integer));
        Dec(NativeUInt(S2), SizeOf(Integer));
        Count := PInteger(S1)^;
        if (Integer(Count) <> PInteger(S2)^) then goto cmp_ptrs;
        Inc(NativeUInt(S1), SizeOf(Integer));
        Inc(NativeUInt(S2), SizeOf(Integer));
    
        for i := 1 to Count shr {$if SizeOf(NativeUInt) = 8}2{$else}1{$endif} do
        begin
          if (S1^ <> S2^) then goto cmp_ptrs;
          Inc(S1);
          Inc(S2);
        end;
    
        {$if SizeOf(NativeUInt) = 8}
        if (Count and 2 <> 0) then
        begin
          if (PCardinal(S1)^ <> PCardinal(S2)^) then goto cmp_ptrs;
          Inc(NativeUInt(S1), SizeOf(Cardinal));
          Inc(NativeUInt(S2), SizeOf(Cardinal));
        end;
        {$endif}
    
        if (PWord(S1)^ <> PWord(S2)^) then goto cmp_ptrs;
        Result := True;
        Exit;
      end else
      begin
      cmp_ptrs:
        Result := (S1 = S2);
      end;
    end;
    
    { TSedgwicComparer }
    
    function TSedgwicComparer.GetHashCode(const Value: string): Integer;
    var
      a, i: Integer;
    begin
      Result := 0;
      a := 63689;
      for i := 1 to Length(Value) - 1 do
      begin
        Result := Result * a + PWordArray(Value)[i];
        a := a * 378551;
      end;
    end;
    
    { TSimpleComparer }
    
    function TSimpleComparer.GetHashCode(const Value: string): Integer;
    var
      i: NativeInt;
      S: PChar;
    begin
      S := Pointer(Value);
      Result := 0;
      if (S <> nil) then
      begin
        Result := PInteger(NativeInt(Value) - 4)^;
    
        for i := 0 to NativeInt(Result) - 1 do
        begin
          Result := Result + Ord(S[i]);
        end;
      end;
    end;
    
    { TShiftComparer }
    
    function TShiftComparer.GetHashCode(const Value: string): Integer;
    var
      i: NativeInt;
      S: PChar;
    begin
      S := Pointer(Value);
      Result := 0;
      if (S <> nil) then
      begin
        Result := PInteger(NativeInt(Value) - 4)^;
    
        for i := 0 to NativeInt(Result) - 1 do
        begin
          Result := Result xor (Result shr (i and 7 + 1)) + Ord(S[i]);
        end;
      end;
    end;
    
    { TFastComparer }
    
    function TFastComparer.GetHashCode(const Value: string): Integer;
    var
      i, X, Count: Integer;
      S: PByte;
    begin
      S := Pointer(Value);
      Result := 0;
      if (S <> nil) then
      begin
        Count := PInteger(NativeInt(Value) - 4)^;
    
        Result := Count;
        for i := 1 to (Count shr (SizeOf(Char) xor 3)) do
        begin
          X := Result xor PInteger(S)^;
          Result := Result * i;
          Inc(Result, X shr 19);
          Inc(S, SizeOf(Integer));
          Inc(Result, X);
        end;
    
        for i := 1 to (Count and ((SizeOf(Char) xor 2) or 1)) do
        begin
          Result := Result * i;
          Inc(Result, Ord(PChar(S)^));
          Inc(S, SizeOf(Char));
        end;
      end;
    end;
    
    
    const
      ITERATIONS_COUNT = 1000000;
      COMPARERS: array[0..4] of TComparerClass = (nil, TSedgwicComparer, TSimpleComparer, TShiftComparer, TFastComparer);
    
    var
      i, c, k: NativeInt;
      VALUES: TArray<string>;
      Time: Cardinal;
      Dictionary: TDictionary<string, Integer>;
    
    begin
      VALUES := [
        'div',
        'span',
        'table',
        'td',
        'tr',
        'th',
        'li',
        'meta',
        'script',
        'style',
        'ol',
        'ul',
        'h1',
        'h2',
        'h3',
        'h4',
        'h5',
        'thead',
        'tbody',
        'html',
        'body',
        'blockquote',
        'address',
        'frame',
        'frameset',
        'pre',
        'button',
        'textarea',
        'strike',
        'del',
        'menu',
        'small',
        'sub',
        'sup',
        'img',
        'fieldset',
        'legend'
      ];
    
      try
        // цикл по всем компарерам
        for c := Low(COMPARERS) to High(COMPARERS) do
        begin
          // конструктор, инфо
          if (COMPARERS[c] = nil) then
          begin
            Write('Default', '...');
            Dictionary := TDictionary<string, Integer>.Create;
          end else
          begin
            Write(COMPARERS[c].ClassName, '...');
            case c of
              1: Dictionary := TDictionary<string, Integer>.Create(TSedgwicComparer.Create);
              2: Dictionary := TDictionary<string, Integer>.Create(TSimpleComparer.Create);
              3: Dictionary := TDictionary<string, Integer>.Create(TShiftComparer.Create);
            else
              // 4:
              Dictionary := TDictionary<string, Integer>.Create(TFastComparer.Create);
            end;
          end;
    
          try
            // заполняем
            for k := Low(VALUES) to High(VALUES) do
              Dictionary.Add(VALUES[k], 0);
    
            // тестируем
            Time := GetTickCount;
            for i := 1 to ITERATIONS_COUNT do
            for k := Low(VALUES) to High(VALUES) do
            begin
              Dictionary.Items[VALUES[k]];
            end;
            Time := GetTickCount - Time;
            Writeln(' ', Time, 'мс');
    
          finally
            Dictionary.Free;
          end;
        end;
      except
        on E: Exception do
          Writeln(E.ClassName, ': ', E.Message);
      end;
    
      // нажать Enter
      Writeln;
      Write('Press Enter');
      Readln;
    end.
    
    function StringHash(const Value: string): Integer;
    var
      i: Integer;
      S: PChar;
    begin
      S := Pointer(Value);
      Result := 0;
      if (S <> nil) then
      begin
        Result := PInteger(NativeInt(Value) - 4)^;
    
        for i := 1 to Result do
        begin
          Result := Result * i + Ord(S^);
          Inc(S);
        end;
      end;
    end;
    
    program Hash;
    
    {$APPTYPE CONSOLE}
    
    {$R *.res}
    
    uses
      Winapi.Windows,
      System.Generics.Collections,
      System.SysUtils,
      System.Classes;
    
    const
      KEYS_COUNT = 1000000;
    
    var
      i: NativeInt;
      HashValue: Integer;
      Keys: TArray<string>;
      Dictionary: TDictionary<Integer, Integer>;
    
    function StringHash(const Value: string): Integer;
    var
      i, X, Count: Integer;
      S: PByte;
    begin
      S := Pointer(Value);
      Result := 0;
      if (S <> nil) then
      begin
        Count := PInteger(NativeInt(Value) - 4)^;
    
        Result := Count;
        for i := 1 to (Count shr (SizeOf(Char) xor 3)) do
        begin
          X := Result xor PInteger(S)^;
          Result := Result * i;
          Inc(Result, X shr 19);
          Inc(S, SizeOf(Integer));
          Inc(Result, X);
        end;
    
        for i := 1 to (Count and ((SizeOf(Char) xor 2) or 1)) do
        begin
          Result := Result * i;
          Inc(Result, Ord(PChar(S)^));
          Inc(S, SizeOf(Char));
        end;
      end;
    end;
    
    function GetHash(const Key: string): Integer;
    var
      a: Integer;
      i: Integer;
    begin
      Result := 0;
      a := 63689;
      for i := 1 to Length(Key) - 1 do
      begin
        Result := Result * a + PWordArray(Key)[i];
        a := a * 378551;
      end;
    end;
    
    begin
      try
        // заполнение
        SetLength(Keys, KEYS_COUNT);
        for i := Low(Keys) to High(Keys) do
          Keys[i] := TGuid.NewGuid.ToString;
    
        // уникальные
        Dictionary := TDictionary<Integer, Integer>.Create;
        try
          for i := Low(Keys) to High(Keys) do
          begin
            HashValue := StringHash{GetHash}(Keys[i]) and (1024 * 1024 - 1);
            Dictionary.AddOrSetValue(HashValue, 0);
          end;
    
          Writeln('Уникальных: ', Dictionary.Count, ', коллизий: ', KEYS_COUNT - Dictionary.Count);
        finally
          Dictionary.Free
        end;
    
        // нажать Enter
        Write('Press Enter');
        Readln;
      except
        on E: Exception do
          Writeln(E.ClassName, ': ', E.Message);
      end;
    end.
    View Code
    function StringHash(const Value: string): Integer;
    var
      i, X, Count: Integer;
      S: PByte;
    begin
      S := Pointer(Value);
      Result := 0;
      if (S <> nil) then
      begin
        Count := PInteger(NativeInt(Value) - 4)^;
    
        Result := Count;
        for i := 1 to (Count shr (SizeOf(Char) xor 3)) do
        begin
          X := Result xor PInteger(S)^;
          Result := Result * i;
          Inc(Result, X shr 19);
          Inc(S, SizeOf(Integer));
          Inc(Result, X);
        end;
    
        for i := 1 to (Count and ((SizeOf(Char) xor 2) or 1)) do
        begin
          Result := Result * i;
          Inc(Result, Ord(PChar(S)^));
          Inc(S, SizeOf(Char));
        end;
      end;
    end;
    View Code
    type
     TStringComparer = Class(TEqualityComparer<String>)
       function Equals(const Left, Right: String): Boolean; Override;
       function GetHashCode(const Value: String): Integer;Override;
     End;
    
    { TStringComparer }
    
    function TStringComparer.Equals(const Left, Right: String): Boolean;
    begin
     result := Left = Right;
    end;
    
    function TStringComparer.GetHashCode(const Value: String): Integer;
    begin
     result := StringHash(value);
    end;
    View Code
    {$OverFlowChecks OFF}
    function GetHash(const Key: String): integer;
    var
      a : Integer;
      i : Integer;
    begin
      Result:=0;
      a:=63689;
      for i:=1 To Length(Key)-1 do begin
        Result:=Result*a+PWordArray(Key)[i];
        a:=a*378551;
      end;
    end;
    View Code
    function StringHash(const Value: string): Integer;
    var
      i: NativeInt;
      S: PChar;
    begin
      S := Pointer(Value);
      Result := 0;
      if (S <> nil) then
      begin
        Result := PInteger(NativeInt(Value) - 4)^;
    
        for i := 0 to NativeInt(Result) - 1 do
        begin
          Result := Result + Ord(S[i]);
        end;
      end;
    end;
    View Code
    function StringHash(const Value: string): Integer;
    var
      i: NativeInt;
      S: PChar;
    begin
      S := Pointer(Value);
      Result := 0;
      if (S <> nil) then
      begin
        Result := PInteger(NativeInt(Value) - 4)^;
    
        for i := 0 to NativeInt(Result) - 1 do
        begin
          Result := Result xor (Result shr (i and 7)) + Ord(S[i]);
        end;
      end;
    end;
    View Code
    {$OverFlowChecks OFF}
    function GetHash(const Key: String): integer;
    var
      a : Integer;
      i : Integer;
    begin
      Result:=0;
      a:=63689;
      for i:=1 To Length(Key)-1 do begin
        Result:=Result*a+PWordArray(Key)[i];
        a:=a*378551;
      end;
    end;
    View Code
    program Test;
    
    {$APPTYPE CONSOLE}
    
    {$R *.res}
    
    uses
      Winapi.Windows,
      System.Generics.Collections,
      System.SysUtils,
      System.Classes;
    
    const
      ITERATIONS_COUNT = 1000000 div 10;
    
    var
      i, k: NativeInt;
      VALUES: TArray<string>;
      Time: Cardinal;
      StringList: TStringList;
      Dictionary: TDictionary<string, Integer>;
    
    type
      THtmlTag = (tagUnknown, tagAddress, tagBlockquote, tagBody, tagButton, tagDel, tagDiv,
        tagFieldset, tagFrame, tagFrameset, tagH1, tagH2, tagH3, tagH4, tagH5, tagHtml,
        tagImg, tagLegend, tagLi, tagMenu, tagMeta, tagOl, tagPre, tagScript, tagSmall,
        tagSpan, tagStrike, tagStyle, tagSub, tagSup, tagTable, tagTbody, tagTd, tagTextarea,
        tagTh, tagThead, tagTr, tagUl);
    
    function StrToHtmlTag(const S: UnicodeString): THtmlTag;
    type
      HugeByteArray = array[0..High(Integer) div SizeOf(Byte) - 1] of Byte;
      HugeWordArray = array[0..High(Integer) div SizeOf(Word) - 1] of Word;
      HugeCardinalArray = array[0..High(Integer) div SizeOf(Cardinal) - 1] of Cardinal;
      HugeNativeUIntArray = array[0..High(Integer) div SizeOf(NativeUInt) - 1] of NativeUInt;
    
      PMemoryItems = ^TMemoryItems;
      TMemoryItems = packed record
      case Integer of
        0: (Bytes: HugeByteArray);
        1: (Words: HugeWordArray);
        2: (Cardinals: HugeCardinalArray);
        3: (NativeUInts: HugeNativeUIntArray);
        4: (A1: array[1..1] of Byte;
            case Integer of
              0: (Words1: HugeWordArray);
              1: (Cardinals1: HugeCardinalArray);
              2: (NativeUInts1: HugeNativeUIntArray);
            );
        5: (A2: array[1..2] of Byte;
            case Integer of
              0: (Cardinals2: HugeCardinalArray);
              1: (NativeUInts2: HugeNativeUIntArray);
            );
        6: (A3: array[1..3] of Byte;
            case Integer of
              0: (Cardinals3: HugeCardinalArray);
              1: (NativeUInts3: HugeNativeUIntArray);
            );
      end;
    var
      Len: Integer;
    begin
      // default value
      Result := tagUnknown;
      if (Pointer(S) = nil) then Exit;
      Len := PInteger(NativeInt(S) - 4)^;
    
      // utf16 ascii
      with PMemoryItems(S)^ do
      if (Len >= 2) then
      case (Words[0]) of // "address", "blockquote", "body", "button", "del", "div", ...
        $0061: if (Len = 7) and (Cardinals2[0] = $00640064) and (Cardinals2[1] = $00650072) and
               (Cardinals2[2] = $00730073) then Result := tagAddress; // "address"
        $0062: case Len of // "body", "button", "blockquote"
                 4: if (Cardinals2[0] = $0064006F) and (Words[3] = $0079) then
                    Result := tagBody; // "body"
                 6: if (Cardinals2[0] = $00740075) and (Cardinals2[1] = $006F0074) and
                    (Words[5] = $006E) then Result := tagButton; // "button"
                 10: if (Cardinals2[0] = $006F006C) and (Cardinals2[1] = $006B0063) and
                     (Cardinals2[2] = $00750071) and (Cardinals2[3] = $0074006F) and
                     (Words[9] = $0065) then Result := tagBlockquote; // "blockquote"
               end;
        $0064: if (Len = 3) then
               case (Cardinals2[0]) of // "del", "div"
                 $006C0065: Result := tagDel; // "del"
                 $00760069: Result := tagDiv; // "div"
               end;
        $0066: case Len of // "frame", "fieldset", "frameset"
                 5: if (Cardinals2[0] = $00610072) and (Cardinals2[1] = $0065006D) then
                    Result := tagFrame; // "frame"
                 8: case (Cardinals2[0]) of // "fieldset", "frameset"
                      $00650069: if (Cardinals2[1] = $0064006C) and (Cardinals2[2] = $00650073) and
                                 (Words[7] = $0074) then Result := tagFieldset; // "fieldset"
                      $00610072: if (Cardinals2[1] = $0065006D) and (Cardinals2[2] = $00650073) and
                                 (Words[7] = $0074) then Result := tagFrameset; // "frameset"
                    end;
               end;
        $0068: case Len of // "h1", "h2", "h3", "h4", "h5", "html"
                 2: case (Words[1]) of // "h1", "h2", "h3", "h4", "h5"
                      $0031: Result := tagH1; // "h1"
                      $0032: Result := tagH2; // "h2"
                      $0033: Result := tagH3; // "h3"
                      $0034: Result := tagH4; // "h4"
                      $0035: Result := tagH5; // "h5"
                    end;
                 4: if (Cardinals2[0] = $006D0074) and (Words[3] = $006C) then
                    Result := tagHtml; // "html"
               end;
        $0069: if (Len = 3) and (Cardinals2[0] = $0067006D) then Result := tagImg; // "img"
        $006C: case Len of // "li", "legend"
                 2: if (Words[1] = $0069) then Result := tagLi; // "li"
                 6: if (Cardinals2[0] = $00670065) and (Cardinals2[1] = $006E0065) and
                    (Words[5] = $0064) then Result := tagLegend; // "legend"
               end;
        $006D: if (Len = 4) then
               if (Words[1] = $0065) then
               case (Cardinals[1]) of // "menu", "meta"
                 $0075006E: Result := tagMenu; // "menu"
                 $00610074: Result := tagMeta; // "meta"
               end;
        $006F: if (Len = 2) and (Words[1] = $006C) then Result := tagOl; // "ol"
        $0070: if (Len = 3) and (Cardinals2[0] = $00650072) then Result := tagPre; // "pre"
        $0073: case Len of // "sub", "sup", "span", "small", "style", "script", "strike"
                 3: if (Words[1] = $0075) then
                    case (Words[2]) of // "sub", "sup"
                      $0062: Result := tagSub; // "sub"
                      $0070: Result := tagSup; // "sup"
                    end;
                 4: if (Cardinals2[0] = $00610070) and (Words[3] = $006E) then
                    Result := tagSpan; // "span"
                 5: case (Cardinals2[0]) of // "small", "style"
                      $0061006D: if (Cardinals2[1] = $006C006C) then Result := tagSmall; // "small"
                      $00790074: if (Cardinals2[1] = $0065006C) then Result := tagStyle; // "style"
                    end;
                 6: case (Cardinals2[0]) of // "script", "strike"
                      $00720063: if (Cardinals2[1] = $00700069) and (Words[5] = $0074) then
                                 Result := tagScript; // "script"
                      $00720074: if (Cardinals2[1] = $006B0069) and (Words[5] = $0065) then
                                 Result := tagStrike; // "strike"
                    end;
               end;
        $0074: case Len of // "td", "th", "tr", "table", "tbody", "thead", "textarea"
                 2: case (Words[1]) of // "td", "th", "tr"
                      $0064: Result := tagTd; // "td"
                      $0068: Result := tagTh; // "th"
                      $0072: Result := tagTr; // "tr"
                    end;
                 5: case (Cardinals2[0]) of // "table", "tbody", "thead"
                      $00620061: if (Cardinals2[1] = $0065006C) then Result := tagTable; // "table"
                      $006F0062: if (Cardinals2[1] = $00790064) then Result := tagTbody; // "tbody"
                      $00650068: if (Cardinals2[1] = $00640061) then Result := tagThead; // "thead"
                    end;
                 8: if (Cardinals2[0] = $00780065) and (Cardinals2[1] = $00610074) and
                    (Cardinals2[2] = $00650072) and (Words[7] = $0061) then
                    Result := tagTextarea; // "textarea"
               end;
        $0075: if (Len = 2) and (Words[1] = $006C) then Result := tagUl; // "ul"
      end;
    end;
    
    begin
      VALUES := [
        'div',
        'span',
        'table',
        'td',
        'tr',
        'th',
        'li',
        'meta',
        'script',
        'style',
        'ol',
        'ul',
        'h1',
        'h2',
        'h3',
        'h4',
        'h5',
        'thead',
        'tbody',
        'html',
        'body',
        'blockquote',
        'address',
        'frame',
        'frameset',
        'pre',
        'button',
        'textarea',
        'strike',
        'del',
        'menu',
        'small',
        'sub',
        'sup',
        'img',
        'fieldset',
        'legend'
      ];
    
      try
        // бинарный поиск
        begin
          Write('Бинарный поиск(TStringList)...');
          StringList := TStringList.Create;
          try
            for k := Low(VALUES) to High(VALUES) do StringList.Add(VALUES[k]);
            StringList.Sorted := True;
    
            Time := GetTickCount;
            for i := 1 to ITERATIONS_COUNT do
            for k := Low(VALUES) to High(VALUES) do
            begin
              StringList.IndexOf(VALUES[k]);
            end;
            Time := GetTickCount - Time;
            Writeln(' ', Time, 'мс');
          finally
            StringList.Free;
          end;
        end;
    
        // хеш
        begin
          Write('Хеш поиск(Dictionary)...');
          Dictionary := TDictionary<string, Integer>.Create;
          try
            for k := Low(VALUES) to High(VALUES) do
              Dictionary.Add(VALUES[k], 0);
    
            Time := GetTickCount;
            for i := 1 to ITERATIONS_COUNT do
            for k := Low(VALUES) to High(VALUES) do
            begin
              Dictionary.Items[VALUES[k]];
            end;
            Time := GetTickCount - Time;
            Writeln(' ', Time, 'мс');
          finally
            Dictionary.Free;
          end;
        end;
    
        // кодогенерация
        begin
          Write('Кодогенерация(CachedSerializer)...');
    
          Time := GetTickCount;
          for i := 1 to ITERATIONS_COUNT do
          for k := Low(VALUES) to High(VALUES) do
          begin
            StrToHtmlTag(VALUES[k]);
          end;
          Time := GetTickCount - Time;
          Writeln(' ', Time, 'мс');
        end;
    
        // нажать Enter
        Writeln;
        Write('Press Enter');
        Readln;
      except
        on E: Exception do
          Writeln(E.ClassName, ': ', E.Message);
      end;
    end.
    View Code
    function StringHash(const Value: string): Integer;
    var
      i: NativeInt;
      S: PChar;
    begin
      S := Pointer(Value);
      Result := 0;
      if (S <> nil) then
      begin
        Result := PInteger(NativeInt(Value) - 4)^;
    
        for i := 0 to NativeInt(Result) - 1 do
        begin
          Result := Result xor (Result shr (i and 7 + 1)) + Ord(S[i]);
        end;
      end;
    end;
    View Code
    procedure TForm23.Button1Click(Sender: TObject);
    var i, k, T: integer;
        L: TStringList;
        s: string;
        D: TDictionary<string, TObject>;
        //ST: THtStringTrie;
        O: TObject;
    begin
      L:=TStringList.Create;
      L.Add('div');
      L.Add('span');
      L.Add('table');
      L.Add('td');
      L.Add('tr');
      L.Add('th');
      L.Add('li');
      L.Add('meta');
      L.Add('script');
      L.Add('style');
      L.Add('ol');
      L.Add('ul');
      L.Add('h1');
      L.Add('h2');
      L.Add('h3');
      L.Add('h4');
      L.Add('h5');
      L.Add('thead');
      L.Add('tbody');
      L.Add('html');
      L.Add('body');
      L.Add('blockquote');
      L.Add('address');
      L.Add('frame');
      L.Add('frameset');
      L.Add('pre');
      L.Add('button');
      L.Add('textarea');
      L.Add('strike');
      L.Add('del');
      L.Add('menu');
      L.Add('small');
      L.Add('sub');
      L.Add('sup');
      L.Add('img');
      L.Add('fieldset');
      L.Add('legend');
      D := TDictionary<string, TObject>.Create;
      for i := 0 to L.Count - 1 do
        D.Add(L[i], TObject.Create);
      //ST := THtStringTrie.Create();
      //for i := 0 to L.Count - 1 do
      //  ST.Add(L[i], TObject.Create);
      T := GetTickCount;
      for i := 1 to 1000000 do
      begin
        for k := 0 to L.Count -1 do
          D.TryGetValue(L[k], O)
          //ST.Find(L[k], O);
      end;
      Caption := inttostr(GetTickCount - T);
    end;
    View Code
    {$OverFlowChecks OFF}
    function GetHash(const Key: String): integer;
    var
      a : Integer;
      i : Integer;
    begin
      Result:=0;
      a:=63689;
      for i:=1 To Length(Key)-1 do begin
        Result:=Result*a+PWordArray(Key)[i];
        a:=a*378551;
      end;
    end;
    View Code
    function CalcStrCRC32(const s: string): cardinal;
    var p: pchar;
    begin
      Result := $FFFFFFFF;
      p := pointer(s);
      if p <> nil then
        while p^ <> #0 do
        begin
          Result := (((Result shr 8) and $00FFFFFF) xor (Ccitt32Table[(Result xor byte(p^)) and $FF]));
          inc(p);
        end;
    end;
    View Code
    procedure TMain.Button3Click(Sender: TObject);
    const
      CRC32_POLYNOMIAL = $EDB88320;
    var
      i, k, T      : integer;
      L            : TStringList;
      Ccitt32Table : array[0..255] of longint;
    
      function crc32(crc : longint; const c : byte) : longint;
      begin
        crc32 := (((crc shr 8) and $00FFFFFF) xor (Ccitt32Table[(crc xor c) and $FF]));
      end;
    
      procedure BuildCRCTable;
      var
      i, j, value : DWORD;
      begin
      for i := 0 to 255 do
      begin
      value := i;
      for j := 8 downto 1 do
      begin
      if ((value and 1) <> 0) then
      value := (value shr 1) xor CRC32_POLYNOMIAL
      else
      value := value shr 1;
      end;
      Ccitt32Table[i] := value;
      end
      end;
    
    
    function GetHash1(const Key: String): integer;
    var p: pchar;
    begin
      Result := $FFFFFFFF;
      p := pointer(Key);
      if p <> nil then
        while p^ <> #0 do
        begin
          Result := (((Result shr 8) and $00FFFFFF) xor (Ccitt32Table[(Result xor byte(p^)) and $FF]));
          inc(p);
        end;
    end;
    
    {$OverFlowChecks OFF}
    function GetHash2(const Key: String): integer;
    var
      a : Integer;
      i : Integer;
    begin
      Result:=0;
      a:=63689;
      for i:=1 To Length(Key)-1 do begin
        Result:=Result*a+PWordArray(Key)[i];
        a:=a*378551;
      end;
    end;
    {$OverFlowChecks On}
    
    
    begin
      BuildCRCTable;
    
      L:=TStringList.Create;
      L.Add('div');
      L.Add('span');
      L.Add('table');
      L.Add('td');
      L.Add('tr');
      L.Add('th');
      L.Add('li');
      L.Add('meta');
      L.Add('script');
      L.Add('style');
      L.Add('ol');
      L.Add('ul');
      L.Add('h1');
      L.Add('h2');
      L.Add('h3');
      L.Add('h4');
      L.Add('h5');
      L.Add('thead');
      L.Add('tbody');
      L.Add('html');
      L.Add('body');
      L.Add('blockquote');
      L.Add('address');
      L.Add('frame');
      L.Add('frameset');
      L.Add('pre');
      L.Add('button');
      L.Add('textarea');
      L.Add('strike');
      L.Add('del');
      L.Add('menu');
      L.Add('small');
      L.Add('sub');
      L.Add('sup');
      L.Add('img');
      L.Add('fieldset');
      L.Add('legend');
    
      T := GetTickCount;
      for i := 1 to 1000000 do
      begin
        for k := 0 to L.Count -1 do
          GetHash1(L[k]);
      end;
      Edit1.Text := inttostr(GetTickCount - T);
    
      T := GetTickCount;
      for i := 1 to 1000000 do
      begin
        for k := 0 to L.Count -1 do
          GetHash2(L[k]);
      end;
      Edit2.Text := inttostr(GetTickCount - T);
    end;
    View Code
    var
      stream: TBytesStream;
      s1: string;
      s2: string;
    begin
      stream := TBytesStream.Create;
    
      stream.WriteData(TEncoding.ANSI.GetBytes('test'), 4);
      s1 := TEncoding.ANSI.GetString(stream.Bytes); // заполнит 8192 символов вместо 4
      s2 := TEncoding.ANSI.GetString(stream.Bytes, 0, 4);
    
      ShowMessageFmt('stream: %d' + #13#10 + 's1: %d' + #13#10 + 's2: %d', [stream.Size, s1.Length, s2.Length]);
      FreeAndNil(stream);
    end;
    View Code
  • 相关阅读:
    快排 [模板]
    翻硬币
    Euphoria与量子波动速读
    高精度例题
    Div3 595 E
    Div 595 C1 C2
    常用 STL 整理
    CF 595 Div3 B2
    【思维】复杂度均摊+并查集——icpc cerc 2019 Saba1000kg
    离散化+圆直线交点+转化——icpc cerc 2019 D
  • 原文地址:https://www.cnblogs.com/marklove/p/9746485.html
Copyright © 2020-2023  润新知