-
Content Count
242 -
Joined
-
Last visited
-
Days Won
2
Everything posted by balabuev
-
Is it really that bad to Use boolean parameters to make your functions do two things?
balabuev replied to Mike Torrettinni's topic in General Help
DisableWindow with boolean parameter is a bad name, by the same reason why dontUseWidget is a bad name. As already described in this topic. -
Is it really that bad to Use boolean parameters to make your functions do two things?
balabuev replied to Mike Torrettinni's topic in General Help
Agree. -
Is it really that bad to Use boolean parameters to make your functions do two things?
balabuev replied to Mike Torrettinni's topic in General Help
My viewpoint to the topic's initial question: Whole WinAPI is written this way. I mean, almost every function provides flags parameter, which alters the function behavior. WinAPI also have examples of Enable/Disable like cases: ShowWindow(wnd, SW_HIDE); EnableWindow(wnd, FALSE); I thingk, it's ok, and it's a kind of well known pattern. -
This can be achieved by setting form's PopupMode to pmAuto (can't say, why it's not default): if FCreatingMainForm then WndParent := 0 else WndParent := Application.ActiveFormHandle; // <------ ...
-
I have related (opposite) question: how to prevent Delphi from showing main form of the project on project opening? I would prefer not to show anything.
-
Can you also provide the code, which shows the dialog?
-
You do something special in your application's code. It's obvious, because the issue cannot be reproduced with simple test project.
-
An XML DOM with just 8 bytes per node
balabuev replied to Erik@Grijjy's topic in Tips / Blogs / Tutorials / Videos
Just as an idea: FFreeList can be implemented as a linked list, without any additional allocations. -
When sorting a “StringList” is very costly
balabuev replied to dummzeuch's topic in Tips / Blogs / Tutorials / Videos
Ahh, sorry , missed that link. Then my previous message can be deleted. -
When sorting a “StringList” is very costly
balabuev replied to dummzeuch's topic in Tips / Blogs / Tutorials / Videos
@dummzeuch Your problem is not in sorting algorithm at all. Trying to optimize sorting algorithm you just solving the wrong task. Even faster way will be to copy the data into some array, sort the array and then copy data back: type TDataItem = record S: string; O: TObject; Checked: Boolean; end; TData = array of TDataItem; var FData: TData; procedure TForm1.Button1Click(Sender: TObject); var c: Cardinal; i: Integer; c2: Cardinal; begin c := GetTickCount; CheckListBox1.Items.BeginUpdate; try SetLength(FData, CheckListBox1.Items.Count); // Copy data from UI for i := 0 to High(FData) do // control. begin // FData[i].S := CheckListBox1.Items[i]; // FData[i].O := CheckListBox1.Items.Objects[i]; // FData[i].Checked := CheckListBox1.Checked[i]; // end; // c2 := GetTickCount; SortList(0, High(FData), SortCompare); // Sort data in array. c2 := GetTickCount - c2; for i := 0 to High(FData) do begin CheckListBox1.Items[i] := FData[i].S; // Copy sorted data CheckListBox1.Items.Objects[i] := FData[i].O; // back. CheckListBox1.Checked[i] := FData[i].Checked; // end; finally CheckListBox1.Items.EndUpdate; c := GetTickCount - c; end; Edit1.Text := IntToStr(c); // Whole time, including UI updates. Edit2.Text := IntToStr(c2); // Sort only time. end; With 10000 items (!) this code run in: Whole time, including UI updates - 1.5 secs (the control is slow, nothing to do with that). Sort only time - 15 msecs. 15 msecs for sorting of 10000 items! -
When sorting a “StringList” is very costly
balabuev replied to dummzeuch's topic in Tips / Blogs / Tutorials / Videos
I've uses the following test with 100 items in list (item count as in your initial post): procedure TForm1.FormCreate(Sender: TObject); var i: Integer; begin for i := 0 to 99 do // Just init the list with some data. begin CheckListBox1.Items.Add('Long long long string ' + IntToStr(Random(1000))); CheckListBox1.Items.Objects[i] := TObject(i); CheckListBox1.Checked[i] := (Random > 0.5); end; end; function TForm1.SortCompare(Item1, Item2: Integer): Integer; begin Result := CompareStr(CheckListBox1.Items[Item1], CheckListBox1.Items[Item2]); end; procedure TForm1.SortList(L, R: Integer; SCompare: TJCHListSortCompare); var I, J, P: Integer; tmpObj: TObject; tmpStr: string; tmpChecked: Boolean; begin repeat I := L; J := R; P := (L + R) shr 1; repeat while SCompare(I, P) < 0 do Inc(I); while SCompare(J, P) > 0 do Dec(J); if I <= J then begin // exchange I and J tmpStr := CheckListBox1.Items[I]; tmpObj := CheckListBox1.Items.Objects[I]; tmpChecked := CheckListBox1.Checked[I]; CheckListBox1.Items[I] := CheckListBox1.Items[J]; CheckListBox1.Items.Objects[I] := CheckListBox1.Items.Objects[J]; CheckListBox1.Checked[I] := CheckListBox1.Checked[J]; CheckListBox1.Items[J] := tmpStr; CheckListBox1.Items.Objects[J] := tmpObj; CheckListBox1.Checked[J] := tmpChecked; if P = I then P := J else if P = J then P := I; Inc(I); Dec(J); end; until I > J; if L < J then SortList(L, J, SCompare); L := I; until I >= R; end; procedure TForm1.Button1Click(Sender: TObject); var c: Cardinal; begin c := GetTickCount; CheckListBox1.Items.BeginUpdate; try SortList(0, CheckListBox1.Items.Count - 1, SortCompare); finally CheckListBox1.Items.EndUpdate; end; Edit1.Text := IntToStr(GetTickCount - c); end; With BeginUpdate/EndUpdate run time is 32 msecs. Without BeginUpdate/EndUpdate - 422 msecs. As for me, even 32 msecs is a way too big for sorting 100 items, but it not 2 seconds! -
When sorting a “StringList” is very costly
balabuev replied to dummzeuch's topic in Tips / Blogs / Tutorials / Videos
Quite strange. Because in my tests they did a drammatic difference (I've used TCheckListBox for test). -
An XML DOM with just 8 bytes per node
balabuev replied to Erik@Grijjy's topic in Tips / Blogs / Tutorials / Videos
The price is - you cannot have DOMs, smaller than the OS memory page (4KB). -
Customizing source editor
balabuev replied to Mike Torrettinni's topic in Tips / Blogs / Tutorials / Videos
Customized colors in black theme + Inconsolata font. Quality image link: https://i.ibb.co/3dDkPNQ/image.png -
When sorting a “StringList” is very costly
balabuev replied to dummzeuch's topic in Tips / Blogs / Tutorials / Videos
Sorting time like 2 seconds is not about sorting at all. It's absolutely crazy . The solution is simple: wrap your sorting with Items.BeginUpdate/Items.EndUpdate. And it's not so important which sort algorithm you will use. QuickSort is good enough. -
The Case of Delphi Const String Parameters
balabuev replied to Mike Torrettinni's topic in RTL and Delphi Object Pascal
agree 🙂 -
The Case of Delphi Const String Parameters
balabuev replied to Mike Torrettinni's topic in RTL and Delphi Object Pascal
var G: string; CriticalSection: ...; procedure TForm11.Button1Click(Sender: TObject); begin G := 7.ToString; // Init with non contant string data. for i := 0 to 1 do begin TTask.Run(procedure var localStr: string; begin CriticalSection.Asquire; // Fetch G into local variable under critical section protection. localStr := G; // CriticalSection.Release; // A(localStr); end); end; end; I claim, that even if we rewrite the code with critical section, it will still not work with your new implementation. -
The Case of Delphi Const String Parameters
balabuev replied to Mike Torrettinni's topic in RTL and Delphi Object Pascal
So, then please argue, why this code is not correct. In which exact place. -
The Case of Delphi Const String Parameters
balabuev replied to Mike Torrettinni's topic in RTL and Delphi Object Pascal
"is correct" means that even in current implementation it will (and should) work fine. And so, your new implementation should also not raise any exceptions. -
The Case of Delphi Const String Parameters
balabuev replied to Mike Torrettinni's topic in RTL and Delphi Object Pascal
Wrong. At least in the context I speaking about. Lets take the code: procedure A(st: string); var TmpLocal: boolean; begin TmpLocal := _AddRefConst(str); try UnLockString(Str); // MakeTheRefCountPositive(str) unlock before B B(st); LockString(str); // MakeTheRefCountNegative(str) lock before C C(st); UnLockString(Str); B(st); LockString(str); C(st); UnLockString(Str); B(st); LockString(str); C(st); UnLockString(Str); B(st); LockString(str); C(st); finally _ReleaseConst(str, TmpLocal); end; end; The initial user's code itself (without our additions) is correct and should work without any bugs or exceptions. During the invokation of this code reference counter will be switched from positive to negative and back several times. Because this is what your LockString/UnlockString function do. So, lets execute this (fully correct) code in two threads concurrently passing the value of the same global variable G into both: var G: string; procedure TForm11.Button1Click(Sender: TObject); begin G := 7.ToString; // Init with non contant string data. TTask.Run(procedure begin A(G); end); TTask.Run(procedure begin A(G); end); end; So, both running A procedures will share same string data and same reference count. And they both will switch this single shared reference count from negative to positive and back in unpredictable order. This single observation lead me to conclusion, that your way is wrong. -
The Case of Delphi Const String Parameters
balabuev replied to Mike Torrettinni's topic in RTL and Delphi Object Pascal
It was global variable. -
The Case of Delphi Const String Parameters
balabuev replied to Mike Torrettinni's topic in RTL and Delphi Object Pascal
Thats not true. I've showed it in previous posts. -
The Case of Delphi Const String Parameters
balabuev replied to Mike Torrettinni's topic in RTL and Delphi Object Pascal
This is impossible because of unpredictable conditions, loops, etc: procedure A(st: string); begin UnLockString(Str); B(st); if SomeCondition then begin LockString(Str); C(st); end; UnLockString(Str); B(st); end; Also, if you add LockString before call of C from A, then you also should add it when calling C from B: procedure B(const st: string); begin LockString(Str); C(st); end; And, actually before any call. And, finally, returning to threads (even without interlocking aspect): You have two states of a string - it can be either locked or unlocked during execution. But, you really lock shared string data. So, having several threads we may run into situation, in which this shared string data should be locked in one thread and unlocked in another thread at the same time. -
The Case of Delphi Const String Parameters
balabuev replied to Mike Torrettinni's topic in RTL and Delphi Object Pascal
Ok. Then let's call many different procedures procedure A(st: string); begin _AddRef(str); try B(st); C(st); B(st); C(st); B(st); C(st); B(st); C(st); finally _Release(str); end; end; The power of RefCount (as it currently implemented), that AddRef/Release and try/finally is introduced in the A procedure only ones. Moreover, this try/finally is shared among all managed variables in this procedure. And what is more, some cases do not need all this stuff at all: var st: string; // Variable, external to procedure. procedure A; begin B(st); C(st); B(st); C(st); B(st); C(st); B(st); C(st); end;