Jump to content

Anders Melander

Members
  • Content Count

    2289
  • Joined

  • Last visited

  • Days Won

    117

Everything posted by Anders Melander

  1. Anders Melander

    Skia versus VCL for plotting points

    Yes, as long as all implementations set pixels via direct memory access then they should perform the same and then benchmarking is pointless. I haven't looked at the new revision to see if that is the case.
  2. Anders Melander

    Skia versus VCL for plotting points

    If you're focusing on performance then you should perform the pixel loop in Y-X order instead of X-Y order. - and replace all the constant divisions with reciprocal multiplications. E.g. x/50 = x * (1/50).
  3. Anders Melander

    SudokuHelper - Example for uncoupled design via interfaces

    Okay. Here goes: You can but don't need to do bit fiddling. We just need to store 3 different states in the pointer; Unassigned Assigned Locked - being assigned It's easy to identify the first two states; If the pointer value is nil then the pointer is unassigned, if it's non-nil then it's assigned. But what about the locked state? Well, for a pointer to an object we can take advantage of the fact that memory allocations are aligned so the lower n bits will always be zero and can be (mis)used to store a lock flag. However since it's a pointer we can just as well just use a pointer value that are known never to be returned by the memory manager. For example ordinal 1. var FSingleton: TSingleton = nil; function Singleton: pointer; const MagicValue = pointer(1); begin if (TInterlocked.CompareExchange(FSingleton, MagicValue, nil) = nil) then FSingleton := TSingleton.Create; // Wait for value to become valid while (FSingleton = MagicValuel) do YieldProcessor; Result := FSingleton; end; Now you're mixing two different arguments. I'm not opposing full pointer exchange. I'm opposing the optimistic object instantiation (which presumably will cause a lock in the memory manager but regardless will be costlier than doing an explicit lock).
  4. Anders Melander

    Hot Reload in Delphi?

    I don't think we're talking about the same.
  5. The entry point is the begin...end block in the dpr file. You can instantiate whatever you want from there. The default is to create the mainform (and whatever "autocreate" forms/modules you have configured) in there. The first form to be created with Application.CreateForm becomes the main form. If you don't want a main form then just don't use Application.CreateForm. Oh, and btw, Application.Run is the message loop.
  6. Anders Melander

    SudokuHelper - Example for uncoupled design via interfaces

    It doesn't need to be, FTOH you can use the low bits of the pointer as a spin-lock flag. That's rather condescending. It's not that I'm not comfortable with it. It's just a solution I personally wouldn't use. I would say that what constitutes "good" is subjective and not defined by "because it is".
  7. Anders Melander

    Hot Reload in Delphi?

    Not really. It's not the loading of the EXE that takes time. It's the application startup, login, select various application stuff, navigate to the POI, etc. Imagine if you were developing the Delphi IDE and was working on some problem that could only be reproduced with a specific project. How long time does it take to start the IDE, load the project, etc.
  8. Anders Melander

    Hot Reload in Delphi?

    Not in this project. It's a C/S desktop application and there hasn't been a need for logging. No, what I'm talking about is the compile, debug, edit cycle.
  9. Anders Melander

    Hot Reload in Delphi?

    I'm often working on applications where it can take 5-10 minutes to launch the application and navigate to the point of interest. Hot reload could save me hours every day.
  10. Anders Melander

    SudokuHelper - Example for uncoupled design via interfaces

    The critical section is only an object because Embarcadero chose to make it one. It doesn't need to be. A spin lock is virtually costless and does not require any instantiation. Works, yes, but I beg to differ on the good part. It's not a pattern I would use. Too "clever".
  11. Anders Melander

    SudokuHelper - Example for uncoupled design via interfaces

    Yes, I already acknowledged that. Having a Rudy moment?
  12. Anders Melander

    SudokuHelper - Example for uncoupled design via interfaces

    Yes, but you can't use TMonitor without an instance which is exactly when we need it. A simply spinlock would probably be the cheapest in this particular case, but my example was just to illustrate what I meant. Keyword here is Lazy
  13. Anders Melander

    SudokuHelper - Example for uncoupled design via interfaces

    Got it. No race condition then. My point was that since the code instantiates an object it isn't as lockless as it appears. The locking being performed is just out of view. A critical section would be much cheaper - and in plan view. var HelperRegistryLock: TCriticalSection; InternalHelperRegistry: IHelperRegistry; function HelperRegistry: IHelperRegistry; begin // Once InternalHelperRegistry has been assigned no locking occurs if (InternalHelperRegistry = nil) then begin // Locking here only happens when there's a race to create the instance HelperRegistryLock.Enter; try if (InternalHelperRegistry = nil) then // Locking inside MM only happens here - a single time InternalHelperRegistry := THelperRegistry.Create; finally HelperRegistryLock.Leave; end; end; Result := InternalHelperRegistry; end; initialization HelperRegistryLock := TCriticalSection.Create; finalization InternalHelperRegistry := nil; HelperRegistryLock.Free; end.
  14. Anders Melander

    SudokuHelper - Example for uncoupled design via interfaces

    The possible race condition I referred to has to do with the (presumably reference counted) lifetime of InternalHelperRegistry but since I haven't looked at the rest of the code there might not be a problem - for example if InternalHelperRegistry is guaranteed to stay alive elsewhere. With regard to locklessnes, doesn't the instantiation of an object cause a lock in the memory manager?
  15. Anders Melander

    Delphi Compilers - # lines of code

    Why? One is a compiler. The other is not(-ish).
  16. Anders Melander

    SudokuHelper - Example for uncoupled design via interfaces

    Yes it does seem to come from that SO thread. The problem as I see it is that it mixes a lock free solution, that's meant to operate on pointers, with reference counted interfaces. Also I don't like the practice of creating an object and then freeing it if it's not needed anyway, but that's besides the point.
  17. Anders Melander

    SudokuHelper - Example for uncoupled design via interfaces

    Doesn't look thread safe to me. I haven't looked at the code apart from the snippet you posted, but as far as I can see there's a race condition.
  18. Anders Melander

    SynEdit bracket highlight

    Yes. I'm not using that project at the moment so I haven't kept it up to date.
  19. Anders Melander

    Skia versus VCL for plotting points

    No doubt but not by that much. I would guess it would be about 25% faster than TBitmap.ScanLine. I.e. around 45 mS on my system. My point was more that it's not really fair to benchmark anything against TCanvas.Pixels since it's known to be dead slow. It's more of a convenience feature. Without having profiled the code I think the TBitmap.ScanLine implementation mostly suffers from the overhead of the call to GdiFlush inside TBitmap.GetScanLine. Since the original implementation writes the bitmap in X-Y order I duplicated that in order to be fair but this also means that the TBitmap.ScanLine implementation performs Width*Height calls to GetScanLine and thus GdiFlush. I circumvented this by caching the scanline row pointers in an array (without this it would have been slower than using TCanvas.Pixels). The X-Y order also means that each pixel write trashes the CPU cache - It should be significant faster in Y-X order.
  20. Anders Melander

    SynEdit bracket highlight

    The version I use works. I don't have time to check the difference in how we do it but you can see for yourself if you want to: https://bitbucket.org/anders_melander/dwscriptstudio/src/15b205a8a7b4d461b786452aa4e0ee548779fe92/Source/amScriptDebuggerMain.pas#lines-1184
  21. Anders Melander

    inherited dynamic message handlers

    I would guess that the override is based on the message number but it should be easy to determine; Just try it.
  22. Anders Melander

    brc32.exe no longer available in D11?

    The omission of brc32.exe is probably an installer bug Use brcc32.exe instead or better yet, use the MS resource compiler rc.exe
  23. Anders Melander

    Skia versus VCL for plotting points

    I just did: TCanvas.Pixels: 320 mS skia4delphi: 130 mS TBitmap.Scanline: 60 mS
  24. Here's a C implementation: https://github.com/yparitcher/libzmanim The code looks well written.
  25. You could roll your own: https://en.wikibooks.org/wiki/Computer_Programming/Hebrew_calendar Here's some code but I have no idea about what language that is: http://www.chelm.org/jewish/calendar/algorithms.html
×