Jump to content

Alex7691

Members
  • Content Count

    25
  • Joined

  • Last visited

  • Days Won

    1

Everything posted by Alex7691

  1. Alex7691

    Rapid.Generics revamp

    Hello everyone, Last week I (unsuccessfully) tried to use the Rapid.Generics library in a specific project. After replacing the std TDictionary/TList with the Rapid.Generics equivalents, the application fell apart within the first 10 seconds of testing, which was quite disappointing. Having some spare time during the weekend, I decided to give it a shot and see if I could make it work properly, at least fixing the most important and visible issues. As a result, I am now sharing my changes so others can benefit from them or contribute. https://github.com/Alexandre-Atozed/Rapid.Generics.v2 Improvements (Readme contains a more detailed list): Fixed multiple bugs Refactored and streamlined the code Removed some unused code Added 123 unit tests, creating a comprehensive test suite The modified code passes all tests and is also free of memory leaks. The real world application is being tested with it now and the initial results are promising. One specific scenario where I replaced the std TDictionary with the Rapid.Generics one (a notification bus where a dictionary is used to map the instances) had a performance increase of 10x or more which is beyond what I would expect and too good to ignore. Any feedback or contributions are welcome! Cheers,
  2. Alex7691

    Rapid.Generics revamp

    Thanks. Responding to your questions: a) The only metrics I have is the size of the executable. Using Rapid.Generics, I got a slightly smaller executable. b) Most of these classes that you mentioned are not necessary for most containers (the sync objects are needed for the TThreadList<>, TThreadedQueue<>. But if you don't use them, Delphi smart linker won't include them.
  3. Alex7691

    Rapid.Generics revamp

    Hi Stefan, In our application there is a notification bus which internally has 2 dictionaries. The main one has an object (the "observable") as the key and a list of objects (each object has references to observers and notification methods) as the value. The second dictionary also has an object (the "observer") as the key and and Integer as the value. The dictionary may contain a large number of objects (dozens of thousands) and at some point in time all the objects need to be freed. So when ObjA (an observable) is being destroyed it will notify all it's observers. Then it will remove itself from the dictionary and all oberservers will also be removed if they are only observing ObjA. This is where the new dictionary performance surprised me. The notification happens faster (because retriving the values from the keys is faster), but more importantly removing them from the dictionary is way faster than the previous version based on std TDictionary.
  4. Alex7691

    Rapid.Generics revamp

    Tested using Win32 and Win64 compilers only for now. Android and Linux, it's possible in a near future. Not sure if I'm going to test on any Apple OS, though... Not into MacOS/iOS dev myself. FMX and VCL are UI frameworks and don't have any relevance for the testing.
  5. Alex7691

    Rapid.Generics revamp

    It has also been fixed in the lastest version in github repo. Cheers,
  6. Alex7691

    Rapid.Generics revamp

    True thing. Please update the source code from github repo. It's fixed now and there are a few new test cases to cover TObjectList (tests for TObjectList are not complete yet). Thanks
  7. Alex7691

    Rapid.Generics revamp

    As I said, it started more like a curiosity... like "it's so damn fast, but it's buggy... Can it be fixed to the point of being useful?" And after "wasting" the weekend, here I am
  8. Alex7691

    Rapid.Generics revamp

    Yep, Rapid is a drop-in replacement. Actually my code now has: uses {$IFDEF USE_RAPIDGENERICS} Rapid.Generics, {$ELSE} System.Generics.Collections, System.Generics.Defaults, {$ENDIF} I can just toggle this compiler directive globally and the 3+ MLOC application can be built either using Rapid generics or std System.Generics.Collections, which is a major bonus. At anytime I can just switch this off with minimal impact (e.g. let's say EMB releases a new faster System.Generics.Collections in Delphi 12+x?)
  9. Alex7691

    Rapid.Generics revamp

    Hi Stefan, yes, I know that Spring4D is great but it would be impossible to refactor hundreds of occurrences of different data structures in a massive 3+ MLOC application... Rapid.Generics took me no more than 2 or 3 hours do change the application (of course, excluding many hours devoted to fix the library itself, but I was mostly doing it for fun in a "let's see if I can make it work" spirit). Basically I needed to do a grep seach/replace + a handful of tweaks here and there and voilá... it was building.... Cheers,
  10. Alex7691

    DevEx VCL Components & VCL Styles??

    I have a huge application in production using VCL Styles and the package mentioned above: https://www.almdev.com/prods/stylecontrols/stylecontrols.html The adapter works well with DevExpress grid and other controls like their different tree views. That's all we use from them. We decided to use other StyleControls components (buttons, date editors, page controls) instead of DevExpress ones because: 1) they play well with VCL Styles 2) Their code is much simpler and in general any issue you find can be fixed by yourself in a couple of hours (compared to days to impossible to fix in DevExpress). It's clear that the author just wants to create something that does its job and works well, instead of trying to use every single pattern in any Gang of Four book. 3) They are lightweight insted of the Dx famous kitchen-sink design I strongly recommend it if you are going down the VCL styles route (disclaimer: I'm not related to almdev company) Cheers,
  11. Has anyone had any luck with Tiny.Library (https://github.com/d-mozulyov/Tiny.Library), more specifically with its Generic classes? BTW, Rapid.Generics contains an older/simpler version of its Tiny.Generics unit (https://github.com/d-mozulyov/Rapid.Generics) I did a quick test on a TDictionary and the performance is impressive compared to the standard System.Generics. Collections dictionary. However, some other tests with TList<> , for example, showed random errors that were difficult to identify the cause, such as exceptions in ReallocMem(). In addition, I identified some bizarre bugs in the code, such as in the TArray.InternalSearch() method, see below: class function TArray.InternalSearch<T>(Values: Pointer; Index, Count: Integer; const Item: T; out FoundIndex: Integer; Comparer: Pointer): Boolean; var I: Integer; Helper: TSearchHelper; begin if (Count <= 0) then begin if (Count = 0) then begin FoundIndex := Index; Result := True; <---------- The result cannot be True when Count = 0 Exit; end else begin raise EArgumentOutOfRangeException.CreateRes(Pointer(@SArgumentOutOfRange)); end; end; System.Generics.Collections has a similar code and the result is obviously false: class function TArray.DoBinarySearch<T>(const Values: array of T; const Item: T; out FoundIndex: NativeInt; const Comparer: IComparer<T>; Index, Count: NativeInt): Boolean; var L, H, mid: NativeInt; cmp: NativeInt; begin if Count = 0 then begin FoundIndex := Index; Exit(False); end; I wouldn't expect to find this in a library of this level, unless it has never actually been tested/used. The lack of unit tests is also concerning....
  12. I ran some benchmark applications this week and I found out that the servers built with Delphi 12 are 13-16% faster than the same built with Delphi 10.4. I can't currently pinpoint the exact source of the performance gain but I guess that Move() and others are playing an important part on it. Anyway, very well done! Cheers,
  13. Seems that you are referring to the TMainMenu control. We don't use it in our application. We used the TActionMainMenuBar which renders the menu. Not sure how much code they share and if the same problem affects both, but IIRC, the menu rendered correctly on high DPI monitors and in mixed setups. One thing that's really messed up in TActionMainMenuBar is the customization at runtime via TCustomizeDlg, and it happens all the time regardless of your monitor DPI. I've reported the issue to EMB but no fix so far: https://quality.embarcadero.com/browse/RSP-31714 Other than that we haven't found any major issues so far.
  14. We tested the application in a mixed monitor setup and it behaved in an acceptably manner (built with 10.3.3). I'm not saying that it is perfect. I'm saying that we couldn't find any showstopper issue. But I also found issues with several other applications in the same scenario, including WPF ones. I think MS didn't get it perfect either. As I said, the application has thousands of users around the world and the general feedback has been good. Nobody ever said that "it doesn't look prefessional" because of some minor issue like this.
  15. Alex7691

    VCL and VCL styles - bugs and future

    That's an old post but since I don't come here often, here it goes: David, you are wrong. IntraWeb is not one decade old. IntraWeb was introduced in 1994, as a product, before Delphi 1.0. In the Delphi world it is as "old" as Delphi itself. And IntraWeb's doing fine, for 30 years, thank you. I dare you to name another product/framework that started before IntraWeb and is still around. And, no, DevExpress and TMS were both founded *after* Atozed and IntraWeb. The same argument that you use against IntraWeb is the one that a Python developer uses against your application that you wrote in Delphi: "Hey, nobody uses Delphi anymore!". The Python developer will never get it, simply because he doesn't know it. Cheers
  16. Alex7691

    IntraWeb IWDBGrid Not Populating Properly

    For future readers: IntraWeb support forum is here: https://www.atozed.com/forums/forum-3.html Cheers
  17. @Rollo62 We recently installed Delphi 12 and we are in the process to get the application building with, it which will require some work. We haven't played with Skia4Delphi yet.
  18. This is an rather old thread but I'd like to give my 2c for future readers: I was lead of a team modernizing a huge (300+ forms, 3+ MLOC) Delphi application. The major part of the modernization process was about styling it, using VCL Styles. We used Delphi 10.3 at that time, and then eventually we migrated to Delphi 10.4. It took 3 months and we decided to purchase a 3rd party library (StyleControls) to make the process easier and faster. StyleControls has simliar controls (e.g. buttons) that work better with styles than the standard ones. Besides that, SyleControls have some classes to help styling controls that don't support VCL Styles directly (e.g. the DevExpress grid that we extensively use in our application). Disclosure: I'm not connected to StyleControls company in any way. Regarding VCL code, some hacking was necessary to fix bugs that couldn't be avoided and no workaround was found (mostly runtime patching of VCL classes). We also used the Rodrigo Ruz's VCL Style Utils package, and it also required some tweaking (nothing major though). Repainting of complex forms when resizing can also be problematic. A non-styled VCL form with hundreds of controls will repaint itself very fast and there is very little flicker. The same form when styled will cause a severe and ugly flicker that can't be ignored and we also needed to find ways to reduce or interrupt form refreshing in many scenarios in order to reduce this effect. But basically I disagree with who says that it doesn't look professional, or "not quite there yet". The final result looks nice and professional, although there are things that could be improved and refined. The application has been in production, with thousands of users and the general feedback has always been positive. I think it's totaly worth it.
  19. Alex7691

    ISAPI in Delphi 10.2,10.3 TranslateURI

    This is an old thread that was pointed out to me by an IntraWeb user. I'm adding some information for future readers. IntraWeb has it's own ISAPI classes and doesn't rely at all on Delphi's IsapiHTTP.pas (or any other Delphi Web.* namespace unit). Any bug in that area doesn't affect IntraWeb applications. Cheers,
  20. I've just tested his test application (without ICS, but the same issue will definitely happen). There is nothing wrong with IntraWeb. He's using an Indy-based IntraWeb server. He creates a window handle when his application is receiving an incoming request. The Indy HTTP server spawns a worker thread which is freed afterward. The window handle is released when the thread is destroyed. Then he tries to use the same window handle in a subsequent request, from another thread (there is no guarantee that the original thread which created the window handle hasn't been destroyed). This is documented here: https://docs.microsoft.com/en-us/windows/win32/procthread/terminating-a-thread BTW: his example works when using Http.sys-based IntraWeb application (not Indy) because the threads are obtained from a thread pool and recycled, so the windows created in one request will be still valid in a subsequent request (although I don't recommend his way of using it at all). Given that the application behavior is not only expected but also correct, your statement above is obviously false. Regards
  21. I did not mention ICS at all. I'm pointing at his test case application which does not use ICS. This is a standard AllocateHWnd RTL call and it won't work reliably. That's a fact. Once you mention that you patch AllocateHWnd from ICS code, are you 100% sure that your patch doesn't break anything else that IntraWeb relies on? After saying yourself that you know nothing about IntraWeb, this kind of statement is at least curious. Regards
  22. For future readers: AllocateHWnd is not thread safe and should never be used like that in any multi-threaded application (not only IntraWeb servers). I'll have a look at his example out of curiosity, but this code the way it is now is not recommended, not supported and definitely won't work reliably.
  23. Alex7691

    Debugging problem (multithreaded & Intraweb)

    Hi Arthur, Indeed, IntraWeb DCUs are built with debug info ON. Mainly because the built-in exception logger (Based on Jedi's JCLDebug code) requires the debug information to create an human readable call stack). Also, not sure how many IW developers add the source code to their build (or add them to the browsing path), but I believe it is a considerable number. The ideal is to have 2 sets of DCUs but it would just explode the size of the setup. We are trying different approaches with the build script and setup program. I will have more information about it soon. Unfortunately, Delphi doesn't have any option to filter out some units or paths from debugger. Personally I have other 3rd party libraries for other projects and it is painful to debug certain applications because of this. Cheers,
  24. Alex7691

    Minifing HTML

    Would you mind elaborating why you need it? In general it is not possible to effectively minify HTML content unless it contains heaps of comments. In that case, simple gzip compression for http(s) transmission is as effective as (if not more, i.e. the cost to compress it using gzip is less compared to the cost of minifying it + compressing it and the benefit is almost the same) Cheers
  25. Alex7691

    This implementation is Thread-safe?

    Contention yes, deadlock, no. Actually it is quite the contrary. Deadlocks only occur because more than one lock is used (or one which can't be called recursively, like Windows' SRWLock objects). This document is *really* wrong.
×