-
Content Count
2070 -
Joined
-
Last visited
-
Days Won
29
Everything posted by Attila Kovacs
-
Micro optimization: Split strings
Attila Kovacs replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
My version is rather fun as some kind of pico-optimization. An on the fly enumerator! And also fast and low memory footprint. (And unidirectional π TSplitEnumerator = class; TSplit = record private PValue: pointer; PDelimiter: pointer; public function GetEnumerator: TSplitEnumerator; class function Create(const AValue: string; const ADelimiter: string): TSplit; static; end; TSplitEnumerator = class private FValue: string; FDelimiter: string; FHasNext: boolean; FIndex: integer; FNIndex: integer; FLen: integer; FDelLen: integer; public constructor Create(const ASplit: TSplit); function MoveNext: boolean; {$IFNDEF DEBUG} inline; {$ENDIF} function GetCurrent: string; {$IFNDEF DEBUG} inline; {$ENDIF} property Current: string read GetCurrent; end; { TSplit } class function TSplit.Create(const AValue: string; const ADelimiter: string): TSplit; begin Result.PValue := pointer(AValue); Result.PDelimiter := pointer(ADelimiter); end; function TSplit.GetEnumerator: TSplitEnumerator; begin Result := TSplitEnumerator.Create(Self); end; { TSplitEnumerator } constructor TSplitEnumerator.Create(const ASplit: TSplit); begin FIndex := 1; pointer(FValue) := ASplit.PValue; pointer(FDelimiter) := ASplit.PDelimiter; FLen := Length(FValue); FDelLen := Length(FDelimiter); FNIndex := Pos(FDelimiter, FValue, FIndex); if (FNIndex = 0) then FNIndex := FIndex + FLen; FHasNext := (FLen > 0) and (FNIndex > 0); end; function TSplitEnumerator.GetCurrent: string; begin Result := Copy(FValue, FIndex, FNIndex - FIndex); if FNIndex + FDelLen < FLen then begin FIndex := FNIndex + FDelLen; FNIndex := Pos(FDelimiter, FValue, FIndex); if FNIndex = 0 then FNIndex := FLen + FDelLen; end else FHasNext := False; end; function TSplitEnumerator.MoveNext: boolean; begin Result := FHasNext; end; var s: string; begin for s in TSplit.Create(cShortStr, cDelimiter) do WriteLn(s); end; -
GExperts 1.3.18 experimental twm 2021-02-21 released
Attila Kovacs replied to dummzeuch's topic in GExperts
You let the genie out of the bottle π π€ -
GExperts 1.3.18 experimental twm 2021-02-21 released
Attila Kovacs replied to dummzeuch's topic in GExperts
@FredS Ahm, I know this! "In welchen saisonalen ZeitrΓ€umen sind Coronaviren in Mitteleuropa normalerweise aktiv?" except summer holiday and xmas, 05:00-19:59. -
@Dany Marmur Because the server works faster if you are shouting π
-
@Dany Marmur By the way, do you know why SQL Queries are written in capital letters? π
-
forget it, must be something else.
-
It's not a problem if you use your own TForm descendant as base. Ofc. it's also a bit work to change everything now. I did it back to the days to handle some HDPI bugs.
-
Firedac FDBatchMove.Execute error when last line in double-quote CSV file does not contain linefeed
Attila Kovacs replied to egnew's topic in Databases
This raises a question for me. π€- 6 replies
-
- firedac
- fdbatchmove
-
(and 1 more)
Tagged with:
-
I'm sure there is a mass property modifier in one of the popular experts. Worst case, there is always "sed". π
-
Is there a mature library for generic (multi)set operations? (Edit: Reading my topic, i meant mathematical sets, maybe I could name it List instead of set, the result what counts) I'd imagine that working like this: unit xyz.sets; interface uses System.Generics.Defaults; type TSets<T> = class public type TSet = class private FValues: TArray<T>; public procedure Add(AValue: T); end; private var FSets: TArray<TSet>; FComparer: IEqualityComparer<T>; public constructor Create; function AddSet: TSet; function GetIntersection(ASets: array of TSet): TArray<T>; property Comparer: IEqualityComparer<T> read FComparer write FComparer; end; implementation uses System.SysUtils; { TSets<T> } function TSets<T>.AddSet: TSet; var l: integer; begin Result := TSet.Create; l := Length(FSets); SetLength(FSets, l + 1); FSets[l] := Result; end; { TSets<T>.TSet } procedure TSets<T>.TSet.Add(AValue: T); var l: integer; begin l := Length(FValues); SetLength(FValues, l + 1); FValues[l] := AValue; end; constructor TSets<T>.Create; begin FComparer := TEqualityComparer<T>.Default; end; // O(n^x) function TSets<T>.GetIntersection(ASets: array of TSet): TArray<T>; var i, j, k, l: integer; begin if FComparer = nil then raise Exception.Create('No comparer defined.'); if Length(ASets) > 1 then begin for i := 0 to High(ASets[0].FValues) do for j := 1 to High(ASets) do for k := 0 to High(ASets[j].FValues) do if FComparer.Equals(ASets[0].FValues[i], ASets[j].FValues[k]) then begin l := Length(Result); SetLength(Result, l + 1); Result[l] := ASets[0].FValues[i]; end; end else Result := ASets[0].FValues; end; end. ------ β ------ β ------ β ------ β ------ β ------ β ------ β ------ β ------ program Project1; {$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils, xyz.sets in 'xyz.sets.pas'; var rp: procedure; i: integer; sets: TSets<string>; set1, set2: TSets<string>.TSet; res: TArray<string>; procedure x; begin ExitProcessProc := rp; ReadLn; end; begin ReportMemoryLeaksOnShutdown := True; rp := ExitProcessProc; ExitProcessProc := x; sets := TSets<string>.Create; set1 := sets.AddSet; set2 := sets.AddSet; try set1.Add('hello'); set1.Add('leo'); set2.Add('hello'); set2.Add('bello'); res := sets.GetIntersection([set1, set2]); for i := 0 to High(res) do WriteLn(res[i]); finally set1.Free; set2.Free; sets.Free; end; end.
-
Generic set comparer
Attila Kovacs replied to Attila Kovacs's topic in Algorithms, Data Structures and Class Design
solved, user error. -
Generic set comparer
Attila Kovacs replied to Attila Kovacs's topic in Algorithms, Data Structures and Class Design
LOL <o>, well, now it's revealed! π -
Generic set comparer
Attila Kovacs replied to Attila Kovacs's topic in Algorithms, Data Structures and Class Design
@Leif Uneus Wow, thanks a lot, and also to LU RD if he ever reads this. -
Generic set comparer
Attila Kovacs replied to Attila Kovacs's topic in Algorithms, Data Structures and Class Design
Ahm, i was afraid that using the word "set" would be misleading, and I was right, sorry, but lists are a bit different from multisets again, so I don't know, I need to compare two or more "set of anything" and I'm tired writing it always manually. -
DB Blob being converted to Unicode and should not be
Attila Kovacs replied to Bill Meyer's topic in Databases
depending on the DAC you are using you could try "Data Type Mapping" -
DB Blob being converted to Unicode and should not be
Attila Kovacs replied to Bill Meyer's topic in Databases
I'm not an IB expert but IB BLOB has a default subtype = text. Maybe it was the whole time stored with that subtype but it was fine with ansistrings? -
DB Blob being converted to Unicode and should not be
Attila Kovacs replied to Bill Meyer's topic in Databases
What kind of DB and Field type and DAC? Can you read the data fine with the D2007 app? -
DB Blob being converted to Unicode and should not be
Attila Kovacs replied to Bill Meyer's topic in Databases
does the blob editor showing it in raw hex? do you read the blob as blobfield and stream or as string? -
Quickly zero all local variables?
Attila Kovacs replied to A.M. Hoornweg's topic in RTL and Delphi Object Pascal
We're approaching levels unseen. -
How do you identify bottleneck in Delphi code?
Attila Kovacs replied to Mike Torrettinni's topic in Tips / Blogs / Tutorials / Videos
-
How to create a "HOLE" in a form and align it to HOLE in another form (Hole by Hole)
Attila Kovacs replied to a topic in VCL
Just press ctrl+shift+v instead of ctrl+v. -
add this to your unit or add it to a unit which you include everywhere after "RzTrkBar" in the uses list. interface type TRzTrackBar = class(RzTrkBar.TRzTrackBar) private procedure WMSetCursor(var Msg: TWMSetCursor); message wm_SetCursor; end; implementation procedure TRzTrackBar.WMSetCursor(var Msg: TWMSetCursor); begin end;
-
override the WMSetCursor message for TRzTrackBar
-
@Alberto Paganini You need const in the parameter list, also measure with TStopwatch and not with Now(), and try not to use local string variable, like: function JsonStringToDateTime(const Src: string): TDateTime; const ofs = Ord('0'); var pSrc: PChar; Time: TDateTime; begin if Length(Src) < 19 then Exit(gOutOfScopelDate); pSrc := Pointer(Src); if not TryEncodeDate( // ((Ord((pSrc)^) - ofs) * 1000) + ((Ord((pSrc + 1)^) - ofs) * 100) + ((Ord((pSrc + 2)^) - ofs) * 10) + (Ord((pSrc + 3)^) - ofs), // ((Ord((pSrc + 5)^) - ofs) * 10) + (Ord((pSrc + 6)^) - ofs), // ((Ord((pSrc + 8)^) - ofs) * 10) + (Ord((pSrc + 9)^) - ofs), Result) then Exit(gOutOfScopelDate); if not TryEncodeTime( // ((Ord((pSrc + 11)^) - ofs) * 10) + (Ord((pSrc + 12)^) - ofs), // ((Ord((pSrc + 14)^) - ofs) * 10) + (Ord((pSrc + 15)^) - ofs), // ((Ord((pSrc + 17)^) - ofs) * 10) + (Ord((pSrc + 18)^) - ofs), // 0, // Time) then Exit(gOutOfScopelDate); Result := Result + Time; end;
-
With https://www.delphihtmlcomponents.com/ the sky is the limit. Just an example for selecting year/quartal/month/week/last 4 weeks/last 12 months/5 years (of course, you have to build your own html/css/scripting, but the result is unique)