June 2014 (5)

2014-06-30

Sub-optimized Win64 Delphi compiler: missing branch table for case of

As we already stated here, the Delphi compiler for the Win64 target performs well, as soon as you by-pass the RTL and its sub-optimized implementation - as we do for mORMot.
In fact, our huge set of regression tests perform only 10% slower on Win64, when compared to Win32.
But we got access to much more memory - which is not a huge gain for a mORMot server, which uses very little of RAM - so may be useful in some cases, when you need a lot of structures to be loaded in your RAM.

Slowdown on Win64 is mostly due to biggest pointer size, which will use twice the memory, hence may generate a larger number of cache misses (failed attempts to read or write a piece of data in the cache, which results in a main memory access with much longer latency).
But in Delphi, apart from the RTL which may need more tuning about performance (but seems not to be a priority on Embarcadero side), is also sometimes less efficient when generating the code.
For instance, sounds like if case ... of ... end statements do not generated branch table instructions on Win64, whereas it does for Win32 - and FPC does for any x64 platform it supports.

Continue reading

2014-06-27

RoadMap refreshed

We did some cleaning in the mORMot official RoadMap.
Now feature requests tickets will detail all to-do items we would like to implement.

Current framework RoadMap and implementation is in fact going into a pragmatic direction.
No need to make all framework's unit compatible at once: so we introduced some client-dedicated units, without any dependency on SynCommons.pas.

We would like to implement (in this order):

The CrossPlatform folder already contains units which compile under all Delphi compilers (VCL and FMX), and FPC.

But perhaps we would move the server to Linux, either via FPC, or using Delphi itself!

Continue reading

Tip about Fossil ticket reports

It appears that version 1.25 of Fossil did change the ticket storage behavior:

Enhancements to ticket processing. There are now two tables: TICKET and TICKETCHNG. There is one row in TICKETCHNG for each ticket artifact. Fields from ticket artifacts go into either or both of TICKET and TICKETCHNG, whichever contain matching column names. Default ticket edit and viewing scripts are updated to use TICKETCHNG.

As stated by the official Fossil Change Log.

It appears that it just broke existing reports, so we had troubles with display of the ticket on our site.

Since we managed to find a workable solution, we would like to share it on our blog, to save other users time!

Continue reading

2014-06-22

Audit-trail for ORM change tracking

Since most CRUD operations are centered within the scope of our mORMot server, we implemented in the ORM an integrated mean of tracking changes (aka Audit Trail) of any TSQLRecord.
In short, our ORM is transformed into a time-machine, just like the good old DeLorean!

Keeping a track of the history of business objects is one very common need for software modeling, and a must-have for any accurate data modeling, like Domain-Driven Design.
By default, as expected by the OOP model, any change to an object will forget any previous state of this object. But thanks to mORMot's exclusive change-tracking feature, you can persist the history of your objects.

Enabling audit-trail

By default, change-tracking feature will be disabled, saving performance and disk use.
But you can enable change tracking for any class, by calling the following method, on server side:

 aServer.TrackChanges([TSQLInvoice]);

This single line will let aServer: TSQLRestServer monitor all CRUD operations, and store all changes of the TSQLInvoice table within a TSQLRecordHistory table.

Continue reading

2014-06-09

Performance comparison from Delphi 6, 7, 2007, XE4 and XE6

Since there was recently some articles about performance comparison between several versions of the Delphi compiler, we had to react, and gives our personal point of view.

IMHO there won't be any definitive statement about this.
I'm always doubtful about any conclusion which may be achieved with such kind of benchmarks.
Asking "which compiler is better?" is IMHO a wrong question.
As if there was some "compiler magic": the new compiler will be just like a new laundry detergent - it will be cleaner and whiter...

Performance is not about marketing.
Performance is an iterative process, always a matter of circumstances, and implementation.

Circumstances of the benchmark itself.
Each benchmark will report only information about the process it measured.
What you compare is a limited set of features, running most of the time an idealized and simplified pattern, which shares nothing with real-world process.

Implementation is what gives performance.
Changing a compiler will only gives you some percents of time change.
Identifying the true bottlenecks of an application via a profiler, then changing the implementation of the identified bottlenecks may give order of magnitudes of speed improvement.
For instance, multi-threading abilities can be achieved by following some simple rules.

With our huge set of regression tests, we have at hand more than 16,500,000 individual checks, covering low-level features (like numerical and text marshaling), or high-level process (like concurrent client/server and database multi-threaded process).

You will find here some benchmarks run with Delphi 6, 7, 2007, XE4 and XE6 under Win32, and XE4 and XE6 under Win64.
In short, all compilers performs more or less at the same speed.
Win64 is a little slower than Win32, and the fastest appears to be Delphi 7, using our enhanced and optimized RTL.

Continue reading