Jump to content


  • Content Count

  • Joined

  • Last visited

  • Days Won


balabuev last won the day on March 10 2021

balabuev had the most liked content!

Community Reputation

94 Excellent

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. balabuev

    TTreeNode leak when VCL styles are active

    Actually, I even do not remember, what we discussed here
  2. balabuev

    Calling inherited in Destroy

    Given the simple code: type TMyClass = class end; procedure P; begin var obj := TMyClass.Create; obj.Free; end; Try to count, how many function calls (and especially virtual calls) are performed here. And after that, it's become clear that additional "inherited" call in destructor changes almost nothing.
  3. balabuev

    Delphi 11 High DPI designer

    This manual DPI handling issue will exist forever, and no good solution will be found. Even if the IDE itself will handle some portion of the problem, there will be always bugfull components. And so on, and so on... Only switching the whole UI library to logical points will really help.
  4. balabuev

    RAD Studio 11 Alexandria is now available

    What I want to say, is that icons and overal look is really awesome 😍. As well as the splash screen. This is the first time when splash screen produce "wow effect", I think, since Delphi 4.
  5. Why? I claimed that it uses same amount of fields like conventional hash table with heap allocated entries - and that's true. There is an array of indices - called "buckets", and yes, this is the main table array, which is analogous to array of pointers to entries (nothing "pretty compact"). There is the "next" field in each entry. So, the waste of space is roundly the same. The levels of indirections - are the same and even worse. You also ignored the fact that all entries are preallocated - thus even more waste of space. All entries are stored continuously in a single array - better cache locality - yes, but I've not talked about this. Overall, this topic is a big question. In real app we have a higly unpredictable sequence of memory accesses, because an app is really a big mess (graph) of heap allocated objects, and hash map access code is mixed with accesses of data from the other objects. And moreover, since hashmap has O(1) average access performance, you do not typically access more than a single entry at a time. So, speaking more generally, cache locality in OOP language is more a task for memory manager. And overall it importance for real code is imho exaggerated.
  6. The question is in overall size. If the size is not too big, which is again - typical, then the table with "unnecessary memory indirections" will work faster, because the logic here is simpler. A table, which inlines everything, must also pay its own price to prevent "wasting space by storing pointers" by introducing additional fields, doing bit manipulation and more array element accesses. But, such a table also wastes space because of lower "load factor", and for yet empty slots when SizeOf(Value) > SizeOf(Pointer). Some well known examples: - Java HashMap and Hashtable - heap allocated entries. Well, they have almost no choice, because Java has no structs. The only way to inline is to keep several parallel arrays. - C# Dictionary<K, V> - kind of tricky code, which preallocates all entries in a separate array, and then uses a kind of tiny embedded memory manager to provide entries from this array. As a result it stores two separate arrays (same waste of space) and indexes instead of direct pointers (waste of space; slower). Since all entries are preallocated, then it becomes even more waste of space when SizeOf(Value) > SizeOf(Pointer).
  7. All this is true when working with tiny things, like, for example, mapping int to int. But, in more usual case, like string keys, the effect is shadowed by string handling overhead and the fact that strings themselves are heap allocated.
  8. I suspected you will say this. But, anyway, in real life we use a lot of heap allocated stuff, like objects or strings, so I think there will be no big difference.
  9. I tried to keep the code reasonably simple. Yes, sure, some improvements are possible. Instead of objects we can at least use records for map items with New/Dispose (or even better, with GetMem/FreeMem), as @Stefan Glienke mentioned before (if I've understood right). We can also go futher and try to minimize heap allocations, or use some sort of map item pool, etc. We also can use some initial capacity as you propose. But, this will complicate the demo code, thus, hiding the main idea, which it tries to show. Moreover, map filling is not critical for this particular test. We measure only search speed.
  10. balabuev

    Documentation creation tool

    All this is very funny, but the question remains open. We are searching for appropriate source code documentation tool (except Documentation Insight, which we already know about), which is not outdated, and preferably allows to keep documentation separately from the code.
  11. Does anyone know which tool Embarcadero uses itself to generate source code documentation (reference)?
  12. This is the key line. Now let's think, where this strange "-32000" numbers may araise at all. I'm sure 99.9% that the numbers are received from a Windows API function call, such as GetWindowRect (or similar) in minimized window state (IsIconic(Handle) = True). Simple experiment proves it: procedure TForm1.Timer1Timer(Sender: TObject); var wr: TRect; begin if WindowState = TWindowState.wsMinimized then begin GetWindowRect(Handle, wr); OutputDebugString(PChar(wr.Left.ToString + ', ' + wr.Top.ToString)); end; end; So: With "-32000" left and top values the window is not, of course, within the area of your monitor 1, but this monitor becomes the closest one to the window.
  13. Handling of maximized form state is bugfull even without multi-monitor setup, and even without VCL Styles. Use the following code with a simple memo on a form: procedure TForm1.FormResize(Sender: TObject); begin Memo1.Lines.Add(Width.ToString + ', ' + Height.ToString + ', ' + IsIconic(Handle).ToString); end; Run the project and maximize the form. Minimize the form using taskbar app button. Maximize it back using taskbar app button. You will see that during minimize/maximize steps two OnResize events are fired with different Width/Height values. This was not the case in early Delphi versions, like Delphi 7; this was introduced later along with the Application.MainFormOnTaskbar feature. I'm sure that all such issues are related, and the problem is that they forget to check for IsIconic() whenever appropriate.
  14. I can confirm the issue with the configuration similar to yours: Monitor 1 - 100% (primary) Monitor 2 - 125% App's main form is shown on the primary monitor (1). The bug happens if monitors are related like this (monitor 2 has negative X coordinates in its area) The bug does not happen if monitors are related like this:
  15. Well, several posts above, @vfbb (topic starter) mentioned TEdit as an exmple "to clarify the problem", which is obviously uses text rendering.