Jump to content

Arnaud Bouchez

Members
  • Content Count

    324
  • Joined

  • Last visited

  • Days Won

    25

Everything posted by Arnaud Bouchez

  1. Arnaud Bouchez

    mORMot RecordSaveJSON

    I wrote an answer to your question on our forum. see https://synopse.info/forum/viewtopic.php?pid=29883#p29883
  2. Arnaud Bouchez

    FmxLinux bundling with Delphi and RAD Studio

    Indeed, from the business point of view, they want to push people buying the Entreprise or Architect editions... so get more money... But the weird point is that the (very competent) guy behind FMXLinux made it after quitting EMB... weird talent/HR management for sure.
  3. Arnaud Bouchez

    FmxLinux bundling with Delphi and RAD Studio

    I don't see this announcement as a good sign. From the management/project point of view, they bought a license from the FMX initial developper, who left EMB last year (IIRC) to re-create his own company https://www.fmxlinux.com - EMB dev team was not able to do it on their own anymore. Sad. I worry about Delphi future if they need to rely on external coders for new targets or features. From the technical point of view, Linux was supported - with FPC as compiler - 10 years ago http://web.archive.org/web/20091213100642/http://www.ksdev.com/dxscene/index.html when FMX was called DXScene. So is it a real progress to be able to have back a feature I got 10 years ago, when I bought my lifetime licence to DXScene? BTW the "LifeTime" of my DXScene license did last 1 year only, since it stopped when EMB bought DXScene - I really felt it was some kind of theft at that time. Now their "LifeTime" license is $349 - I really wonder if it is worth it...
  4. Arnaud Bouchez

    Datasnap -> MARS conversion

    Putting the SQL in the URI is IMHO a way (and unsecure) way of defining a service. Leaking the database access (and structure) is a bad practice. This is not REST-oriented at all - see https://en.wikipedia.org/wiki/Representational_state_transfer The first step would be to put the SQL in the REST body, not in the URI. Then there is no reason why MARS shouldn't be able to execute it.
  5. Thanks for the tip! Nice reading. Note that the chapter about multi-thread friendly MM does not take into account the memory consumption of each, which is a pity. In short, FastMM4 is very conservative (consume very low RAM), ScaleMM2 define a per-thread heap so will eat more memory, but it is worth saying that I have seen the Intel TBB MM eats hunderth time more memory than FastMM4 (with peaks at 200x RAM consumption). So I never was able to use TBB on production. Almost the same for jemalloc. Under Linux, a modern glibc has also a great speed - but is a bit paranoid and sometimes SIGKILL the process on some memory error in end-user code. You have some numbers in https://github.com/synopse/mORMot/blob/master/SynFPCCMemAligned.pas#L57
  6. Arnaud Bouchez

    Linux Support on Pro Edition

    I like very much those generated lines: 0000000000456FDF 8944243C mov DWORD PTR [rsp+0x3c],eax 0000000000456FE3 EB00 jmp 0x456fe5 <Project1.initialization()+85> 0000000000456FE5 8B44243C mov eax,DWORD PTR [rsp+0x3c] ... which just do nothing: it jumps to the next opcode, and use an unneeded temporary storage... 🙂 Also check https://web.archive.org/web/20170417182109/https://plus.google.com/103246155735524926641/posts/SbLxpp2DipK The problem is not LLVM, which is able to generate very good assembly, but how LLVM is used as backend from the Delphi compiler. LLVM is a very complex beast, so I don't blame Embarcadero developpers (how many are working on the compiler?), just know how difficult it should be to maintain this path. I am rather pleased with FPC floating point abilities on Linux x86_64. It is less optimized than gcc or llvm for sure when using their aggressive settings, but at least FPC generated assembly is clean and efficient. I usually spend hours in the generated assembly to validate algorithms coded in pascal. SSE2 registers allocation and inlining are not bad with FPC, and it is easy to reach good performance on all Operating Systems, once the code is good on a given processor.
  7. Arnaud Bouchez

    SQLite - FireDAC or ?

    Note that the SQlite3 version embedded with FireDAC tends to be updated at a slow pace, and stick to the Delphi release. It is currently 3.23.1 in Delphi 10.3, whereas the current is 3.28. With an OpenSource or third-party solution, you may be able to update SQlite3 without upgrading the compiler. I have seen requests to upgrade SQlite3 for regulatory or security reasons. 3.23.1 is known to be vulnerable, as reported e.g. by https://www.cvedetails.com/vulnerability-list/vendor_id-9237/Sqlite.html and https://www.zdnet.com/article/sqlite-bug-impacts-thousands-of-apps-including-all-chromium-based-browsers/
  8. Arnaud Bouchez

    Linux Support on Pro Edition

    @Markus Kinzler You are right: I forgot about http://blog.marcocantu.com/blog/2018-october-Delphi-ARC-directions.html So many back & forth! 😞 I prefer very much the FPC stability, and attempt to never break existing code - some Delphi people consider(ed) it conservative, but I find it refreshing. For instance, I would miss shortstring support for sure (are they available in Delphi for Linux?), as IMHO they are a good way to avoid heap allocation and an hidden try...finally block, e.g. for efficient logging or text/JSON/XML generation, if you just append some ASCII characters, and don't mess with encoding. A local shortstring is much more efficient than string in some cases.
  9. Arnaud Bouchez

    Linux Support on Pro Edition

    We use FPC for Linux server-side development, cross-compiling via Lazarus from Windows via https://github.com/LongDirtyAnimAlf/fpcupdeluxe/releases Then we use https://en.wikipedia.org/wiki/Windows_Subsystem_for_Linux to run the executable as console with no VM, and validate the regression tests quickly and efficiently. Even if FPC/Lazarus is Open Source, its compiler is very good. IIRC the Delphi for Linux compiler uses ARC, which could become a real PITA to debug for memory leaks for a server application. At least, FPC has a single memory model on all targets. See http://blog.marcocantu.com/blog/2017-february-delphi-linux-compiler.html for this platform limitations/requirements.
  10. Arnaud Bouchez

    Advice Needed: PDF Graphics Rendering Suite??

    Look into our OpenSource https://github.com/synopse/SynPDF project. It is free, fast, creates small PDF, and you can draw your content using a regular VCL TCanvas: the same code could be used on screen and for the PDF. Also note that there is no "resolution" in PDF, which is uses floating-point coordinates for its vectorial drawings. If you generate from a TCanvas, your code will use integers, so here you may need to tune the resolution - just like with any VCL code.
  11. Arnaud Bouchez

    Pack exe using UPX

    1. It uses less disk, but more memory than a plain exe. 2. I have observed is that the combination of Delphi exe + UPX is often falsely detected as a potential virus threat by some antiviruses. For me, point 2 is a showstopper, since it is frightening for your users.
  12. Arnaud Bouchez

    Allocation-Free Collections

    In fact, it is not allocation-free, it is heap-allocation free, since it needs to allocate its memory from the stack. And note that the stack size can be pretty limited... For instance, if the process is run within IIS, stack size is only 256KB (on 32-bit), which could be too small for using allocation-free collections everywhere. Under Linux, the default thread stack size can be pretty limited in comparison to Windows, too. What we do in practice in our servers code when we need such temporary storage, is to use a 4KB stack-allocated buffer, with optional heap allocation. See https://synopse.info/files/html/api-1.18/SynCommons.html#TSYNTEMPBUFFER There are some methods to pre-initialize the buffer with common patterns (zero bytes, increasing integers, random numbers).... But you need to use pointer arithmetic, whereas this article uses generics so may a little safer. 4KB is OS memory page size, so should already be there, and avoid to reach 256KB numbers.
  13. Arnaud Bouchez

    Recompile Delphi RIO RTL/VCL?

    Use a Delphi version < 2010 (where the enhanced RTTI has been introduced) or FPC/Lazarus, and to something even smaller, https://github.com/rofl0r/KOL or our https://github.com/synopse/LVCL
  14. Arnaud Bouchez

    TurboDB 6 VCL anyone using ?

    As for an embedded database, I would rather use SQlite3 or even FireBird, which has an embedded version. They are OpenSource, cross-platform, well maintained and have high feature set.
  15. Arnaud Bouchez

    log file policies

    On server side, we log a lot of stuff... almost everything possible information. It is needed for post-mortem or post-bug forensic. Of course, our mORMot framework logs automatically all SOA calls, and all ORM and/or SQL process. And it also logs all exceptions. See https://synopse.info/files/html/Synopse mORMot Framework SAD 1.18.html#TITL_73 This was for low-level text logs. At higher level, we also log all high-level SOA calls, in form of local Sqlite3 databases. This is very efficient to make any kind of statistics, via some simple SQL SELECT. https://synopse.info/files/html/Synopse mORMot Framework SAD 1.18.html#TITLE_445
  16. Arnaud Bouchez

    log file policies

    Here is what we usually do: Store logs in a dedicated folder, with proper read policy. -> especially under Unix, all background daemons run with a dedicated user, and the log files have chmod 640 to restrain read access. Always run the logs in Verbose mode, even on production, unless the execution environment is really constrained. (you never know what will happen, and detailed logs is a need for proper investigation, especially on production) -> you need a logging solution which is fast, and can log dozen MB/s with no performance penalty (e.g. our SynLog.pas unit writes in a background thread) Rotate logs to keep history as long as possible -> SynLog.pas has built-in SynLZ-compression of the logs for very fast and efficient rotation Never log passwords, or such sensitive information. -> password are always stored and persisted in salted + hashed form - but when transmitted as parameters, or as settings, they should be encrypted - even a naive encryption may be enough like with a TSynPersistentWithPassword class from SynCommons.pas -> more generally, sensitive information should be handled in memory with strong cryptography, e.g. via our cross-platform CryptDataForCurrentUser() from SynCrypto.pas Have a way to hide unexpected content, when log is automated. -> in mORMot.pas, you can register some sensitive types which parameters will be logged as "***" during SOA automated logging of calls. Ensure all those policies are always setup by default, and on all supported platforms -> today, we should ensure that Linux execution should be not weaker than Windows as a target (and it is easy to make executable safer under Linux) Optionally use a third-party SaaS solution to store your logs in the long term, with proper encryption and search abilities -> like https://livemon.com - server-side written in object pascal 🙂 Most of it is available out-of-the-box in http://mormot.net
  17. Check https://www.delphitools.info/2013/10/30/efficient-string-building-in-delphi/ TStringBuilder has been enhanced in latest Delphi 10.3 IIRC. Our OpenSource `TTextWriter` class, which works on UTF-8 (which is very likely your eventual CSV file encoding), is very fast (it avoids most memory allocation), and has a `TTextWriter.CancelLastComma` method, as you expect. See https://synopse.info/files/html/api-1.18/SynCommons.html#TTEXTWRITER_CANCELLASTCOMMA
  18. This is wrong if the refcount is 1: in that case (which happens when you just appended some texts to a string variable), SetLength() won't copy the string, just call ReallocMem() which is a no-op with FastMM4 over a minus one byte buffer, and put a #0 at the end. See how _UStrSetLength() is implemented in System.pas.
  19. or even try procedure DeleteLastChar(var aText: string; aLastChar: char); inline; var len: {$ifdef FPC}PSizeInt{$else}PInteger{$endif}; begin len := pointer(aText); if len <> nil then begin dec(len); if PChar(pointer(aText))[len^ - 1] = aLastChar then begin PChar(pointer(aText))[len^ - 1] := #0; dec(len^); end; end; end; which has also the advantage of working with both Delphi and FPC. But all these sounds a bit like premature optimization to me... 😞
  20. If you are SURE that the string has a reference count of 1, e.g. if it just has been allocated and not assigned/copied anywhere else, you can simply try: procedure DeleteLastChar(var aText: string; aLastChar: char); inline; begin if (aText <> '') and (aText[length(aText)] = aLastChar) then dec(PInteger(PAnsiChar(pointer(aText)) - SizeOf(integer))^); end; This will avoid a call the heap manager. Then do proper benchmark.
  21. Square of distances is indeed the way I would have done it: faster (no branch, no call), and no complex math.
  22. Arnaud Bouchez

    Pointers are dangerous

    FastMM4, in FullDebugMode is able to track such pointer problems. I always use it, and also the FPC's Heaptrc unit (compile with -gl) which can find some other problems. I use pointers only when the code needs it, mainly for performance reasons. Otherwise, high-level structures like classes or dynamic arrays are just enough.
  23. Why not directly make it `using` and replace the `begin` `end` with `{ }` ? :)
  24. Arnaud Bouchez

    IDE Fix pack for Rio

    Where this information came from? If it is the case, I didn't see any performance enhancement at execution, at least from our mORMot regression tests, which run a lot of performance measurements. In fact, most loop unrolling could even be slower on modern CPUs - for instance, AES unrolled loop which was faster on P4 is slower than a tuned rolled loop. I doubt EMB did make proper compiler optimization in loop unrolling, and let the inlining performance problems remain.
  25. Arnaud Bouchez

    What is the fastest way to check if a file exists?

    I don't see any reason why it shouldn't.
×