-
Content Count
2977 -
Joined
-
Last visited
-
Days Won
106
Everything posted by dummzeuch
-
How to determine the subjective brightness of my screen?
dummzeuch replied to Der schöne Günther's topic in Algorithms, Data Structures and Class Design
But we are not StackOverlfow. Thank god. I''ve got some code for calculating brightness, but this is for converting color bitmaps to grayscale. I'm not sure whether this fits your purpose because perceived brightness of a screen might be different of the brightness of a picture. type TRgbBrightnessChannelEnum = (rcbAverage, rcbFastLuminance, rcbRed, rcbGreen, rcbBlue, rcbLuminance); function GetFastLuminance(_Red, _Green, _Blue: Byte): Byte; begin Result := Round(0.299 * _Red + 0.587 * _Green + 0.114 * _Blue); end; function GetRgbLuminance(_Red, _Green, _Blue: Byte): Byte; var Hls: THlsRec; begin GetRgbHls(_Red, _Green, _Blue, Hls); {$IFDEF dzUseGraphics32} Result := Round(Hls.Luminance * HLSMAX); {$ELSE} Result := Hls.Luminance; {$ENDIF} end; function GetRgbBrightness(_Red, _Green, _Blue: Byte; _Channel: TRgbBrightnessChannelEnum): Byte; begin case _Channel of rcbAverage: Result := Round((_Red + _Green + _Blue) / 3); rcbFastLuminance: Result := GetFastLuminance(_Red, _Green, _Blue); rcbRed: Result := _Red; rcbGreen: Result := _Green; rcbBlue: Result := _Blue; else // rcbLuminance: ; {$IFDEF dzUseGraphics32} Result := Round(GetRgbLuminance(_Red, _Green, _Blue) * HLSMAX); {$ELSE} Result := GetRgbLuminance(_Red, _Green, _Blue); {$ENDIF} end; end; This is from the unit u_dzGraphicsUtils from my dzlib. -
TimSort for Delphi without Generics
dummzeuch posted a topic in Algorithms, Data Structures and Class Design
As already stated in a different thread I have adapted the TimSort implementation for FreePascal I found on github to compile with Delphi 2007 (and probably earlier, but I haven't tried it). The source code is licensed under the Apache License 2.0 and available in my dzlib on OSDN. Note that this currently only sorts an array of integer and is still pretty rough. I'm going to refine quite a bit. There seem to be only 2 (now 2.5 😉 ) TimSort implementations in Pascal / Delphi available. (According to @David Heffernan there is also one in Spring4d.), but none that does not require generics. -
I got bitten by an interface!
dummzeuch replied to Clément's topic in Algorithms, Data Structures and Class Design
... or simply add the _AddRef, _Release (wasn't there a 3rd one?) methods required for an interface implementation to your ancestor class and let them do nothing. -
Install recent Delphi versions on Windows XP
dummzeuch replied to dummzeuch's topic in Delphi IDE and APIs
As long as these PCs are not connected to the Internet or even the LAN, there is no need to update them, if they are "good enough". Unfortunately it is becoming difficult to buy Windows XP compatible hardware. We found only one supplier who guarantees Windows XP compatibility for his motherboards, and we had issues with the test machine we ordered with it. That's why I am currently experimenting with Windows 10 on the "embedded" PCs. I have a bad feeling about this. Windows 10 has just too much of "we are Microsoft, we know best" in it, in particular the enforced updates. I would prefer Linux, but porting the software is way too much work. -
Install recent Delphi versions on Windows XP
dummzeuch replied to dummzeuch's topic in Delphi IDE and APIs
Because I have to maintain some programs that must be run and sometimes debugged under Windows XP on computers that are not or rarely connected to a LAN (so remote debugging is out). So far I have been using Windows 2007 and XE2 but I'm thinking about upgrading these projects, so the question is: How far I can upgrade? (Fun fact: I also have one active program under DOS with Borland Pascal 7 which I have been trying to get rid of for >10 years. Currently it looks like I will get rid of Windows XP before DOS.) -
Given: A computer with a working Delphi 2007 installation using a Network Named User license (with the license server in the LAN). I have reached the user limit on that license. I just use too many computers in parallel at the moment and it's really annoying to have to close the IDE on one computer to be able to open it on another one. We have got enough licenses, so I thought maybe it is possible to install a different Network Named User license on that computer in addition to the existing one and for the same user. Has anybody ever tried this?
-
Install two different licenses for Delphi 2007
dummzeuch replied to dummzeuch's topic in Delphi IDE and APIs
OK, I bit the bullet and tried it: It is possible to import multiple licenses into the license manager if the .slip files have different names (If you buy two licenses separately they have different names, if you buy two licenses at once, there will only be one slip file for both. Luckily we have bought them separately). I don't know yet whether assigning both licenses to the same user name will work as hoped though. The license server did not complain, but it is still possible that it won't work starting more IDEs than originally allowed because there is now an additional license for that user. EDIT: Warning, don't try this (at home or at work): There is apparently no way to remove a license with the Delphi 2007 License Manager (The one from Delphi 10.2 could do that.) -
Install two different licenses for Delphi 2007
dummzeuch replied to dummzeuch's topic in Delphi IDE and APIs
Unfortunately that's not possible in this case. There must be only one user account on these computers and it must have one specific name. (Yes, I known these are peculiar requirements, but these are no ordinary office computers either.) -
atomic setting of a double variable
dummzeuch replied to dummzeuch's topic in Algorithms, Data Structures and Class Design
Hm, yes, could be an option once I get this project to a later Delphi version. Currently it's Delphi 2007, but that should not be a permanent hindrance. -
atomic setting of a double variable
dummzeuch replied to dummzeuch's topic in Algorithms, Data Structures and Class Design
Yeah, good point. I'd need atomic reading code for that too. I guess I didn't think far enough. The alignment would not be a problem, I could make sure it is as required. The use case is one thread reading data from an external device, a different one displaying that data on the screen, and a third one writing it to a file. Most of of the data is integers but there are also two doubles. It doesn't really matter whether the different values match but of course a double must still be a valid double which could be a problem when reading two 4 byte parts from two different double values. Since the data is read at different times only one variable would be changed at any time, so I thought I could maybe get way without any of the heavier sync objects. I guess I'll just stick with a critical section. I know how to use these and it's unlikely that there will be a performance bottleneck here. -
TimSort for Delphi without Generics
dummzeuch replied to dummzeuch's topic in Algorithms, Data Structures and Class Design
Fixed the string order issue. -
TimSort for Delphi without Generics
dummzeuch replied to dummzeuch's topic in Algorithms, Data Structures and Class Design
Here are some timings: sorted reverse half random QuicksortInteger(1000000): 0.05787 0.06269 not done 0.16328 QuickSortPlusInteger(15)(1000000): 0.04744 0.04995 0.24928 0.14548 TimSortInteger(1000000): 0.00214 0.00252 0.00981 0.16411 QuicksortString(1000000): 1.36692 1.00144 not done 1.16640 QuickSortPlusString(15)(1000000): 1.38534 0.99298 0.81605 1.23809 TimSortString(1000000): 0.06285 0.09036 0.16268 1.86726 Sorting 1 million integers or strings respectively. The strings are simply generated with IntToStr for numbers 0 to 999,999 and compared with CompareStr. This means that Sorted, Reverse and half for strings is not really correct, because '10' < '2' etc. I need to fix that, but this is not too bad a dataset for sorting tests either. (I just googled and found that apparently there are some test datasets for sorting algorithm performance. I'll have a look into that.) The numbers are the time in seconds for a single run on my computer. As you can see, TimSort is faster than all of them with the exception of random data, where it is still in the same ballpark. The test program is in the subdirectory Tests\SortingTests. Please note that with the exception of TimSort, these sorting algoritmms are not implemented for best performance but for convenience: They are abstracted from the data and use callbacks to compare and swap items. TimSort currently works directly on the data and uses a callback only for comparison, but my goal is to abstract the algorithm from the data in a similar manner, if possible. -
TimSort for Delphi without Generics
dummzeuch replied to dummzeuch's topic in Algorithms, Data Structures and Class Design
My implementation now uses Pseudo Templates based on include files (please note that the linked article is ancient, so take its C++ references with a grain of salt), so it should be compatible with most Delphi versions (tested with Delphi 2007 and 10.2). The source is on OSDN in my dzlib. It has been tested with sorting dynamic arrays of integers and strings, but should work with anything else that does not include reference counting (so no interfaces yet). It's much slower for strings because of the special code in the MoveItems method which allows for reference counting (for strings, should also ). Unit tests are in the UnitTests\SortingTest subdirectory of dzlib. The units declaring TimSort for Integer and String arrays use the above mentioned template. To get the source, use SubVersion to create a working copy from http://svn.osdn.net/svnroot/dzlib-tools/dzlib/trunk -
When sorting a “StringList” is very costly
dummzeuch posted a topic in Tips / Blogs / Tutorials / Videos
The following code looks innocuous but slows down a program significantly: type TJCHListSortCompare = function(Item1, Item2: Integer): Integer of object; TCheckListBoxWithHints = class(TCheckListBox) private procedure QuickSort(L, R: Integer; SCompare: TJCHListSortCompare); // [...] procedure TCheckListBoxWithHints.QuickSort(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 := Items[I]; tmpObj := Items.Objects[I]; tmpChecked := Self.Checked[I]; Items[I] := Items[J]; Items.Objects[I] := Items.Objects[J]; Self.Checked[I] := Self.Checked[J]; Items[J] := tmpStr; Items.Objects[J] := tmpObj; Self.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 QuickSort(L, J, SCompare); L := I; until I >= R; end; Yes it’s Quicksort and it sorts strings in a TCheckListBox’s Items property, swapping not only the strings but also the objects and the Checked values. Now, run this with, lets say 100 entries. That shouldn’t be any problem for Quicksort, should it? But it takes about 2 seconds on my computer which is muuuuuuch longer than I expected. The same code running on a simple TStringList takes less than 1/10 of a second. Why is that? read on in the blog post -
When sorting a “StringList” is very costly
dummzeuch replied to dummzeuch's topic in Tips / Blogs / Tutorials / Videos
BeginUpdate / EndUpdate didn't make any noticeable difference in my tests. Otherwise I wouldn't have bothered to make any of the other changes. -
32bit RGBA TBitmap to RGB byte stream.
dummzeuch replied to Tommi Prami's topic in Algorithms, Data Structures and Class Design
How often do you access the ScanLine property? I found that it is much faster to get the address of the first line, calculate the offset between lines and add (or subtract) the offset to get the other lines. Also, pointer incrementation is much faster than using an array with indexes. On top of that, make sure to disable range checking in the release code. There is some code that does it in u_dzGraphicsUtils in my dzlib. If I remember correctly I blogged about it too. Edit: Yes I did: https://blog.dummzeuch.de/2019/12/12/accessing-bitmap-pixels-with-less-scanline-calls-in-delphi/ -
Customizing source editor
dummzeuch replied to Mike Torrettinni's topic in Tips / Blogs / Tutorials / Videos
I think that's a side effect of fixes for this problem: https://stackoverflow.com/questions/25295980/delphi-2006-2010-error-cannot-create-file-c-users-admin-appdata-local-temp-ed E.g. if you are using my dzeditorlineendsfix tool. It prevents the font file used by the editor for the line ends to be loaded. Since that is only necessary for Delphi 2006 to 2010 you may not need it any more. -
Customizing source editor
dummzeuch replied to Mike Torrettinni's topic in Tips / Blogs / Tutorials / Videos
I usually turn on "Show tab characters" (source options) and "BRIEF cursor shapes" (display). I also change "Right Margin" to 100. And today I turned off Italic for comments, thanks for that hint. -
When sorting a “StringList” is very costly
dummzeuch replied to dummzeuch's topic in Tips / Blogs / Tutorials / Videos
My sorting functions aren't optimized for speed but for convenience. They take function pointers for comparing and swapping two elements rather than directly working on the data. That's a considerable overhead. My current TimSort doesn't do that yet and I'm not sure whether it will be possible to implement it in such a way, but I will try it. -
When sorting a “StringList” is very costly
dummzeuch replied to dummzeuch's topic in Tips / Blogs / Tutorials / Videos
I just read the Apache License (never did before) and have now added a link to the source code above. Note that the current code can only sort an array of integer and is pretty rough. I'll clean it up a bit today and add more tests. I also started a new thread on this: TimSort for Delphi without Generics. -
The simplest way i can think of is a hosted web server that supports https for your clients (add some kind of logon if you need it) and uses sftp to upload files.
-
When sorting a “StringList” is very costly
dummzeuch replied to dummzeuch's topic in Tips / Blogs / Tutorials / Videos
Impressive: sorted reverse half random QuickSort(10000000): 0.69550 0.72872 not done 1.89622 QuickSort+(12)(10000000): 0.63999 0.65609 3.61170 1.70513 QuickSort+(15)(10000000): 0.63134 0.66484 3.65941 1.72658 QuickSort+(17)(10000000): 0.63200 0.65742 3.58655 1.73312 QuickSort+(20)(10000000): 0.59678 0.62114 3.60640 1.75100 TimSort(10000000): 0.02052 0.03282 0.11939 1.88033 QuickSort(100000000): 8.13450 8.50642 not done 21.52633 QuickSort+(12)(100000000): 7.16910 7.47369 45.95549 19.66967 QuickSort+(15)(100000000): 7.25634 7.49350 45.59182 19.57720 QuickSort+(17)(100000000): 7.15293 7.43410 46.06242 19.69688 QuickSort+(20)(100000000): 7.26109 7.46288 46.09772 20.61769 TimSort(100000000): 0.20487 0.33015 1.12082 23.05309 This is the result of a test sorting an array of 10 Million and 100 milliion integers on my computer. The values are the time in seconds. QuickSort is my regular quicksort implementation QuickSort+ is my optimized quicksort which: choses a pivot by selecting the median between elements Left, Right and (Left + Right) / 2 uses InsertionSort for small sets, if Right - Left < Cutoff (The value in parenthesis is the cutoff.) TimSort is the code from the link above, adjusted so it compiles with Delphi 2007 (no generics). Edit: Here is the source code. Note that It currently can only sort an array of integer. -
When sorting a “StringList” is very costly
dummzeuch replied to dummzeuch's topic in Tips / Blogs / Tutorials / Videos
Don't know whether it's any good, but here is one for free pascal: https://github.com/avk959/LGenerics Unit lgMiscUtils -
When sorting a “StringList” is very costly
dummzeuch replied to dummzeuch's topic in Tips / Blogs / Tutorials / Videos
A ListView would also require lots of messages, but from experience i know that it can easily handle thousands of lines and still be reasonable fast (we're talking about less than 200 here). A VirtualTreeview would be an option, but meaning to add yet another component which i am rather reluctant to do in this case. Another option would be a (virtual) StringGrid, I actually started down that road but decided to try and improve that sorting first. Now I've got a solution that's fast enough and works, so I'll probably leave it as is. -
When sorting a “StringList” is very costly
dummzeuch replied to dummzeuch's topic in Tips / Blogs / Tutorials / Videos
As I said: A virtual ChecklistBox would have been ideal, but unfortunately that mode has been broken since forever. So it's either live with that, or use a different control (ListView?). I'm still considering the latter, but I'm not sure it's worth the effort since it's fast enough now and newer IDEs already come with a similar functionality.