Einzelnen Beitrag anzeigen

EgonHugeist

Registriert seit: 17. Sep 2011
187 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#41

AW: Leerzeichen in String einfügen

  Alt 31. Jan 2016, 17:14
ich mach nun mal den Deckel für mich zu, damit ich die Datei löschen kann. Habe mal 2 Versionen zur Veranschaulichung zum Ausgang einer Fixen-String Länge von 128-Zeichen gemacht.
Hoffe diesmal ist es leserlicher, da ich schönere Typen-Bezeicher gewählt habe.

Mit allen verfügbaren bisher dargelegten plus der 2 anfolgenden Routinen die Benchmarks vornweg:
Zitat von Benchmarks:
Task: Fuege einen "_" -Char an jeder 4. Stelle eines 128 Zeichen langen Strings ein!
Benchmarking DupeString('1234', 1 shl 5) Iterations: 64000000:

Autor: "Mavarik" Function: "MavarikQuadUnderScoreInjector" TickCount: 8250
Autor: "Dejan Vu" Function: "DejanVuQuadUnderScoreInjector" TickCount: 58890
Autor: "EgonHugeist" Function: "leerzeichen" TickCount: 2860
Autor: "Sir Rufo" Function: "StrInsertEveryNthPos" TickCount: 58422
Autor: "EgonHugeist" Function: "EH_StrInsertEveryNthPos_4Chars" TickCount: 12562
Autor: "EgonHugeist" Function: "EH_QuadUnderScoreInjectorBy4" TickCount: 2328
Autor: "EgonHugeist" Function: "EH_QuadUnderScoreInjectorBy8" TickCount: 2235
Autor: "EgonHugeist" Function: "EH_QuadUnderScoreInsertFix128String_a" TickCount: 2468
Autor: "EgonHugeist" Function: "EH_QuadUnderScoreInsertFix128String_b" TickCount: 2063
Version a: (Tiny)
Delphi-Quellcode:
function EH_QuadUnderScoreInsertFix128String_a(Const Text: String): String;
type
  PtrInt = {$IFDEF CPUX64}UInt64{$ELSE}Cardinal{$ENDIF};
  P4Chars = ^T4Chars;
  T4Chars = {$IFDEF UNICODE}UInt64{$ELSE}LongWord{$ENDIF};
  P5CharsRec = ^T5CharsRec;
  T5CharsRec = packed record
    CharQuad: T4Chars;
    UnderScore: Char;
  end;
var
  i: Integer;
  Src: P4Chars;
  Dest: P5CharsRec;
begin
  Assert((Text <> '') and (PLongInt(NativeUInt(Text) - SizeOf(LongInt))^ = 128), 'wrong Text string length!'); //fast get src length
  if (Pointer(Result) = nil) or //result unassigned?
     (PLongInt(NativeUInt(Result) - SizeOf(LongInt))^ <> 159) {PStrRec.Len} or //length different?
     (PLongInt(NativeUInt(Result) - (SizeOf(LongInt) shl 1))^ <> 1) {PStrRec.RefCnt} then //no unique string?
    SetLength(Result,159);
  Src := Pointer(Text);
  Dest := Pointer(Result);
  for i := 0 to 30 do begin
    Dest.CharQuad := Src^; Dest.UnderScore := '_';
    Inc(PtrInt(Dest), SizeOf(T5CharsRec));
    Inc(PtrInt(Src), SizeOf(T4Chars));
  end;
  Dest.CharQuad := Src^;
end;
und Version b: (Huge)
Delphi-Quellcode:
function EH_QuadUnderScoreInsertFix128String_b(Const Text: String): String;
type
  T4Chars = {$IFDEF UNICODE}UInt64{$ELSE}LongWord{$ENDIF};
  P4CharsArray = ^T4CharsArray;
  T4CharsArray = array[0..31] of T4Chars;
  T5CharsRec = packed record
    CharQuad: T4Chars;
    UnderScore: Char;
  end;
  P5CharsArray = ^T5CharsArray;
  T5CharsArray = array[0..31] of T5CharsRec;
var
  Src: P4CharsArray;
  Dest: P5CharsArray;
begin
  Assert((Text <> '') and (PLongInt(NativeUInt(Text) - SizeOf(LongInt))^ = 128), 'wrong Text string length!'); //fast get src length
  if (Pointer(Result) = nil) or //result unassigned?
     (PLongInt(NativeUInt(Result) - SizeOf(LongInt))^ <> 159) {PStrRec.Len} or //length different?
     (PLongInt(NativeUInt(Result) - (SizeOf(LongInt) shl 1))^ <> 1) {PStrRec.RefCnt} then //no unique string?
    SetLength(Result,159);
  Src := Pointer(Text);
  Dest := Pointer(Result);
  Dest[0 ].CharQuad := Src[0 ]; Dest[0 ].UnderScore := '_';
  Dest[1 ].CharQuad := Src[1 ]; Dest[1 ].UnderScore := '_';
  Dest[2 ].CharQuad := Src[2 ]; Dest[2 ].UnderScore := '_';
  Dest[3 ].CharQuad := Src[3 ]; Dest[3 ].UnderScore := '_';
  Dest[4 ].CharQuad := Src[4 ]; Dest[4 ].UnderScore := '_';
  Dest[5 ].CharQuad := Src[5 ]; Dest[5 ].UnderScore := '_';
  Dest[6 ].CharQuad := Src[6 ]; Dest[6 ].UnderScore := '_';
  Dest[7 ].CharQuad := Src[7 ]; Dest[7 ].UnderScore := '_';
  Dest[8 ].CharQuad := Src[8 ]; Dest[8 ].UnderScore := '_';
  Dest[9 ].CharQuad := Src[9 ]; Dest[9 ].UnderScore := '_';
  Dest[10].CharQuad := Src[11]; Dest[11].UnderScore := '_';
  Dest[11].CharQuad := Src[12]; Dest[12].UnderScore := '_';
  Dest[13].CharQuad := Src[13]; Dest[13].UnderScore := '_';
  Dest[14].CharQuad := Src[14]; Dest[14].UnderScore := '_';
  Dest[15].CharQuad := Src[15]; Dest[15].UnderScore := '_';
  Dest[16].CharQuad := Src[16]; Dest[16].UnderScore := '_';
  Dest[17].CharQuad := Src[17]; Dest[17].UnderScore := '_';
  Dest[18].CharQuad := Src[18]; Dest[18].UnderScore := '_';
  Dest[19].CharQuad := Src[19]; Dest[19].UnderScore := '_';
  Dest[20].CharQuad := Src[20]; Dest[20].UnderScore := '_';
  Dest[21].CharQuad := Src[21]; Dest[21].UnderScore := '_';
  Dest[22].CharQuad := Src[22]; Dest[22].UnderScore := '_';
  Dest[23].CharQuad := Src[23]; Dest[23].UnderScore := '_';
  Dest[24].CharQuad := Src[24]; Dest[24].UnderScore := '_';
  Dest[25].CharQuad := Src[25]; Dest[25].UnderScore := '_';
  Dest[26].CharQuad := Src[26]; Dest[26].UnderScore := '_';
  Dest[27].CharQuad := Src[27]; Dest[27].UnderScore := '_';
  Dest[28].CharQuad := Src[28]; Dest[28].UnderScore := '_';
  Dest[29].CharQuad := Src[29]; Dest[29].UnderScore := '_';
  Dest[30].CharQuad := Src[30]; Dest[30].UnderScore := '_';
  Dest[31].CharQuad := Src[31];
end;
Man sieht, wenn man den letzten Tropfen aus dem Stein drücken will, lohnt sich auch mehr Code.. Lehren aus den unterschiedlichen Verhalten bei gleicher Aufgabenstellung kann sich jeder selber ziehen.

Wenn keiner weitere Anregungen hat, oder du die Zeit nicht findest.. Deckel zu.

Habt Spaß
Angehängte Dateien
Dateityp: pas QuadUnderScoreInjections.pas (17,2 KB, 3x aufgerufen)

Geändert von EgonHugeist (31. Jan 2016 um 18:20 Uhr) Grund: File was buggy
  Mit Zitat antworten Zitat