Synopse Open Source - Tag - zipmORMot MVC / SOA / ORM and friends2024-02-02T17:08:25+00:00urn:md5:cc547126eb580a9adbec2349d7c65274DotclearEnhanced Faster ZIP Support in mORMot 2urn:md5:194b963ed6b1488b09f09d891354ed702021-05-08T08:49:00+01:002021-05-08T08:46:27+01:00Arnaud BouchezmORMot Framework64bitavxAVX2blogcompressioncrccrc32cCrossPlatformDelphilibdeflatemORMotmORMot2performancezip<p>The <code>.zip</code> format is from last century, back to the <a href="https://en.wikipedia.org/wiki/DOS">early DOS days</a>, but can still be found everywhere. It is even hidden when you run a <code>.docx</code> document, a <code>.jar</code> application, or any Android app!<br />
It is therefore (ab)used not only as archive format, but as application file format / container - even if in this respect <a href="https://sqlite.org/appfileformat.html">using SQLite3 may have much more sense</a>.</p>
<p><img src="https://blog.synopse.info?post/public/blog/zipfile.jpg" alt="" /></p>
<p>We recently enhanced our <a href="https://github.com/synopse/mORMot2/blob/master/src/core/mormot.core.zip.pas">mormot.core.zip.pas</a> unit:</p>
<ul>
<li>to support Zip64,</li>
<li>with enhanced <code>.zip</code> read/write,</li>
<li>to have a huge performance boost during its process,</li>
<li>and to integrate better with signed executables.</li>
</ul> <h3>Zip64 Support for Huge Files</h3>
<p>First of all, our unit now supports the long-awaited Zip64 extension. In a nutshell, it allows to store files bigger than 4GB, or have the total <code>.zip</code> bigger than 4GB - which is the maximum 32-bit stored size.</p>
<h3>TZipRead TZipWrite Enhancements</h3>
<p>The high-level <code>TZipRead</code> and <code>TZipWrite</code> classes were deeply refactored and enhanced. Not only Zip64 support has been added, but can ignore and skip some files during reading - a very efficient way of deleting files in a <code>.zip</code>. Some additional methods have been introduced, e.g. to quickly validate a <code>.zip</code> file integrity. Cross-platform support has been enhanced.</p>
<p>Previous <code>TZipRead</code> used to map the whole <code>.zip</code> file into memory. It was convenient for small content. But huge files won't fit into a Win32 application memory: you could not use Zip64 on 32-bit executables - not very convenient for sure! And performance of memory-mapped files is typically slower than explicit Seek/Read calls, since the Kernel is involved to handle page faults and read the data from disk. This had to be fixed.<br />
Now a memory buffer size is specified to <code>TZipRead.Create</code> constructors, which will contain the last bytes of the <code>.zip</code> file, in which the directory header would appear - and very efficiently parsed at opening. Then, actual content decompression would use regular Seek/Read calls, only when needed. Of course, if the data is available in the memory buffer - which is the case for the last files, or for smaller <code>.zip</code> - it will take it from there. So the new approach seems a very reasonable implementation - typically faster than other zip library I have seen, and our previous code.</p>
<h3>LibDeflate Support</h3>
<p>Perhaps the main change of this refactoring, is the <a href="https://github.com/ebiggers/libdeflate">libdeflate library</a> integration. It is a library for fast, whole-buffer DEFLATE-based compression and decompression. In practice, when working on memory buffers (not streams), it is able to leverage very efficient ASM code for modern CPUs (like AVX), resulting to be much faster than any other zlib implementation around. If streams are involved - e.g. when decompressing huge files - then we fallback to the regular zlib code.</p>
<p>LibDeflate implementation of crc or adler checsums is astonishing: on my Intel Core i5 <code>crc()</code> went from 800MB/s to 10GB/s. And this crc is used for <code>.zip</code> file checksums, so it really helps.<br />
Also compression and decompression are almost twice faster than regular zlib, thanks to a full rewrite of the deflate engine, targeting modern CPUs, and using tuned asm for bottlenecks.<br />
Last but not least, you can use higher compression levels - regular zlib understand from 0 (stored) to 9 (slowest), but libdeflate accepts 10..12 for even higher compression - at the expense of compression speed which becomes very slow, but decompression will be in par with other levels.</p>
<p>We statically linked libdeflate, so you don't need to have an external library. Sadly, it is currently available for FPC only, since Delphi linking is an incompatible mess.</p>
<p>Note that libdeflate will be used anywhere in <em>mORMot</em> where deflate/zip buffer compression is involved, so for instance regular HTTP/HTTPS on-the-fly <code>gzip</code> compression will be much faster, and even some unexpected part of the framework would benefit from it - e.g. our default RESTful URI authentication used the zlib <code>crc()</code> for its online checksum, so each REST request is slightly faster.</p>
<h3>Integrated to Signed Executables</h3>
<p>The last enhancement was also the ability to append a <code>.zip</code> content to an existing "signed" executable. Since "mORMot 1", we allowed to find and read any <code>.zip</code> content appended to an executable. But if you digitally signed this executable, you would need to re-sign it after appending. Not very convenient, e.g. when you build a custom <code>Setup.exe</code>.</p>
<p>We added some functions to include the <code>.zip</code> content within the signature itself, allowing to store some additional data or configuration in a convenient format, without requiring to sign the executable again.</p>
<h3>Use the Source, Luke!</h3>
<p>Check the <a href="https://github.com/synopse/mORMot2/blob/master/src/core/mormot.core.zip.pas">mormot.core.zip.pas</a> unit in our Open Source repository!</p>Transmission between mORMotsurn:md5:8d3096cb2b28e2c5d4ba288f00b77d812012-11-30T16:42:00+01:002012-12-03T07:53:03+01:00AB4327-GANDImORMot FrameworkblogcompressionDelphiJSONmORMotperformanceRestzip<p>Little mORMots have a very efficient transmission protocol, in their
mountains...</p>
<blockquote>
<p>Most mORMots are highly social and use loud whistles to communicate with one
another, especially when alarmed.<br />
As stated <a href="http://en.wikipedia.org/wiki/Marmot">by Wikipedia</a></p>
</blockquote>
<p><img border="0" src="http://www.toynutz.com/0002RockChuck7.jpg" width="360" height="215" /></p>
<p>In a comment of the <a href="http://robertocschneiders.wordpress.com/2012/11/22/datasnap-analysis-based-on-speed-stability-tests/">already
quoted blog article about DataSnap performance issues</a>, Tom asked this
interesting question about mORMot, after I presented how we like to use
<a href="https://blog.synopse.info?post/post/2011/03/11/HTTP-server-using-fast-http.sys-kernel-mode-server"><em>
http.sys</em> kernel-mode server</a> to achieve best performance possible over
HTTP:</p>
<blockquote>
<p>What about TCP communication, http is not the only Internet protocol.
<em>Protobuf, Thrift, MsgPack, BSON</em> etc, is binary protocol and http i big
overhead in some systems.<br />
Did http.sys enable use of tcp/ip socket protocol?</p>
</blockquote> <p>Thanks Tom for the comments.</p>
<div>
<p>But we must take care <a href="http://en.wikipedia.org/wiki/OSI_model">not
to mix the layers</a> in such cases!</p>
<h3>Transmission Protocol</h3>
<p>About transmission protocol, HTTP is a layer over TCP, and has not such a
big overhead.<br />
By design, <em>http.sys</em> won’t enable use of TCP/IP protocol (unless you
<a href="http://synopse.info/forum/viewtopic.php?id=953">use Windows 8 and
switch to websockets mode</a>, but it is not very well supported over all
networks).<br />
A TCP layer won’t be faster in practice. </p>
<p>But <em>mORMot</em> proposes other transmission protocols, such as
in-process calls, or named pipe or GDI messages (the later is very efficient in
practice, but only works locally).<br />
You can have several protocols at once, in just one code line each, to publish
an unique server. Or you can host several servers on the same process/service.
For instance, you can do load-balancing in a logical n-Tier architecture, using
GDI messages locally <a href="https://blog.synopse.info?post/post/2012/05/25/Domain-Driven-design">between
application and domain layer</a>, but a public HTTP front end.</p>
<h3>Application Layer</h3>
<p>About application data content format, we use JSON and a REST/stateless
routing scheme.</p>
<p>We found out JSON to be very efficient, better than XML, and comparable to
binary protocols in most cases. We can optionally use deflate/zip compression
or our own very optimized SynLZ algorithm, to reduce bandwidth.<br />
In practice JSON is much more easy to work with from any client (including
JavaScript/AJAX or even a human brain) than any binary layout. Packet
inspection software will like JSON much more than a binary content.</p>
<p>For instance, <em>mORMot</em> is able to use a “stretched” layout when
returning a list of data, sending them as an array of items with the headers
just sent once, instead of an array of objects. We have to embed small BLOBs as
Base64, but the framework handles and prefers a direct RESTful remote access
via a dedicated URI and direct binary download via a regular GET.</p>
<p>We use a <a href="https://blog.synopse.info?post/post/2011/06/02/Fast-JSON-parsing">very fast in-place
JSON parsing</a> (like a SAX approach) instead of a DOM-like template.<br />
And when it deals with database access, we directly convert the DB client
buffers into JSON content, with no temporary storage. <a href="http://blog.synopse.info/post/2012/09/14/Updated-mORMot-benchmarks-on-another-HW-configuration">
Performance is outstanding</a>, especially insertion in BATCH mode and reading
results can be even better when internal ORM cache is enabled (it was disabled
for this testing, on purpose). Those benchmarks let shine mORMot's JSON
marshalling of the data, to and from object instances and the database
optimized drivers.</p>
<h3>Nice and easy mORMot</h3>
<p>From our tests on real world data, due to the TCP packet overhead, using
JSON over HTTP is just a very good option, just in-between XML/SOAP and
proprietary binary content, without any compatibility concern.</p>
</div>Synopse PDF Engine 1.18urn:md5:e08d62456641ed00772f24a8c551faf72012-11-28T20:47:00+01:002012-11-28T21:01:32+01:00AB4327-GANDISynopse PDF engineDelphiPDFperformanceSourceSynopsezip <p>Our <em>SynPdf</em> library was released as part of every <em>mORMot</em>
version.<br />
But the stand-alone .zip was still in 1.15 revision.</p>
<p>I have updated it, and now it reflects the latest version from our source
code repository (i.e. 1.18).<br />
Open Source, working from Delphi 5 up to XE3.</p>
<p>Thanks to nice proposals - <a href="http://synopse.info/forum/viewtopic.php?id=932">like those from Sinasa</a> -
conversion engine from metafile content is pretty complete.<br />
Font fallback has been introduced for glyphs not available in the current font,
and some issues have been identified and fixed.<br />
<em>SynPdf</em> unit can now link to standard <em>ZLib.pas</em> unit if you
want to use it stand-alone and do not need our faster <em>SynZip.pas +
deflate.obj + trees.obj</em>.</p>
<p>Forum and feedback are <a href="http://synopse.info/forum/viewtopic.php?id=952">welcome on our
forum</a>.<br />
Direct download link is available in <a href="http://synopse.info/fossil/wiki?name=Downloads">our Download section</a>.</p>Total Commander 64 bit is using... Lazarus and FPCurn:md5:553ca887ab1e177a8321cb525ecc49fc2011-12-04T09:46:00+01:002011-12-05T10:13:01+01:00AB4327-GANDIPascal Programming64bitblogDelphiFreePascalTotalCommanderzip<p>I'm a long-time registered user of <a href="http://ghisler.com">Total
Commander</a>.</p>
<p>This tool is my daily file manager. I never use <em>Windows Explorer</em>,
since <em>Total Commander</em> is just faster, more easy to use (especially
with the keyboard), has a lot of plug-ins. I even created my own plug-ins to
access some custom file formats, and navigate into them just like with any
folder. And it includes a lot of well written commands for FTP access or file
comparison, which made other tools (like <em>WinMerge</em>) unnecessary.</p>
<p>There is a new <em>beta</em> version of Total Commander available,
which targets Windows 64 bit. I just thought: 'Whoo, this is a real-world
Delphi XE2 64 application'. I downloaded and tried it. Worked as expected, and
integrates seamlessly with Windows Seven (for the shell extensions).
Then I took a look at the executable... and discovered it was not compiled with
Delphi XE2... but with FPC !</p> <p>The 32 bit version appears to be compiled with Delphi 2 - yes, this is an
OLD version (the first 32 bit version) - but this is <a href="http://www.ghisler.ch/board/viewtopic.php?t=23548">what the TC author himself
states</a>.</p>
<p>As a result, the 32 bit version executable is small and efficient. And,
honestly, you can write a nice Unicode software without using generics and all
the new Delphi features...</p>
<p>When looking at the 64 bit supplied version, it was obvious to me that even
if the tool was behaving the same as the 32 bit version (fast and native user
interface), the gears were not the same. It seems to have been compiled with
the great Open Source <a href="http://freepascal.org/">Free Pascal
Compiler</a> - using not the VCL, but the cross-platform <a href="http://www.lazarus.freepascal.org/">Lazarus project</a>. I do not know if the
LCL components where used, or some <em>Total Commander</em>-custom components
(which I think is more than probable, knowing Ghisler's skill and hand-tuning
abilities).</p>
<p>It is even clear if you look <a href="http://www.ghisler.com/history.txt">at
the application history</a>:</p>
<pre>
14.07.10 Added: Start work on conversion to Lazarus/Free Pascal in preparation for 64-bit version
</pre>
As I wrote <a href="https://blog.synopse.info?post/post/2010/08/14/FPC-and-Delphi%3A-toward-a-%22fratricidal-war%22">some time
ago in this blog</a>, FPC team published a 64 bit compiler using the
Delphi/object pascal language in 2006. Whereas the "official" Win64 support
just appeared this year, with Delphi XE2.
<p>Christian Ghisler is working with FPC for a lot of time for the PocketPC
(... and now <a href="http://ghisler.com/android.htm">Android</a>!) freeware
versions of his tool.</p>
<p>I'm very happy to see such a world-wide spread application using FPC and
Lazarus tandem. There are open source alternatives to FireMonkey and Delphi
XE2. Not a feature-like, but with another architecture, another rendering,
another coding spirit, another cross-platform abilities, another
mind openness... Even Delphi is using FPC as compiler <a href="https://blog.synopse.info?post/post/2011/08/08/Our-mORMot-won-t-hibernate-this-winter%2C-thanks-to-FireMonkey">
when targeting iOS</a>.</p>
<p>Feedback and comments are <a href="http://synopse.info/forum/viewtopic.php?id=535">welcome on our forum</a>!</p>Which Delphi compiler produces faster code?urn:md5:90c0d8c8c4c005ed7158d0a063c761df2011-06-16T21:55:00+02:002011-07-02T10:54:28+02:00AB4327-GANDIPascal Programming64bitasmcompressionDelphiGoodPracticemultithreadParsingperformanceSourceSQLite3Testingzip<p>After a <a href="http://stackoverflow.com/questions/6372017/does-delphi-xe-produce-faster-code-than-delphi-2007">
question on StackOverflow</a>, I wanted to comment about the speed of generated
code by diverse Delphi compiler versions.</p>
<p>Since performance matters when we write general purpose libraries like ours,
we have some feedback to propose:</p>
<ul>
<li>The 4,500,000 unitary tests of our <a href="https://blog.synopse.info?post/category/Open-Source-Projects/SQLite3-Framework">SQlite3 ORM
Framework</a>;</li>
<li>The <a href="https://blog.synopse.info?post/post/2010/06/26/Pure-pascal-LZO-and-SynLZ-compression-units">SynLZ
compression algorithm</a>.</li>
</ul> <h3>Compiler benchmark from our Open Source ORM framework</h3>
<p>When running our unit tests with Delphi 7, Delphi 2007 and Delphi 2010
compilers, I found out some speed improvement between Delphi 7 and Delphi 2007,
but nothing noticeable between Delphi 2007 and 2010. Delphi 2010 generated code
was found out to be even a bit slower, probably due to the overhead of RTTI and
some caching issues. I don't have a Delphi XE compiler at hand, but I guess
it's somewhat the same as Delphi 2010 - this latest version was mainly a bug
fix release (e.g. about generics), AFAIR.</p>
<p>I spent a lot of time in the asm view (Alt-F2) when I write low-level pascal
code, and use a profiler. So I usually notice any difference between Delphi
compiler versions.</p>
<p>IMHO the main improvement in the generated code was the <code>inline</code>
keyword for methods and functions/procedures, available in Delphi 2007 and not
in Delphi 7. Another improvement was a more aggressive register re-use.</p>
<p>Floating-point generated code is still slow and sometimes awfull (the FWAIT
is still produced, even if not necessary any more, and inlining floating-point
code could be even <a href="http://delphitools.info/2011/02/08/the-limitations-of-delphis-inline/">worse
than with no inlining</a>!).</p>
<p>What is interesting about our framework, and all those tests is that it does
process a lot of data, using its own low-level units, coded in very tuned
pascal for best performance. The unit tests provided (more than 5,400,000
individual tests) work on real data (numerical conversion or UTF-8 text
processing), with a lot of diverse processes, including low-level conversions,
text parsing, object allocations, multi-threading and Client/Server
orientation. So here, the code generation by the compiler does make a
difference.</p>
<p>The process is run mainly inside our framework's libraries. We use our own
RawUTF8 string type, and not the generic string. Therefore, the bottleneck is
not the VCL nor the Windows API, but only pure Delphi compiled code. In fact,
we avoid most API calls, even for UTF-8 encoding or numerical conversions.</p>
<p>Of course, I tried this benchmark with <code>PUREPASCAL</code> conditional
set, i.e. not running the optimized part in asm, but rely on only "pure pascal"
code.</p>
<h3>Feedback from the SynLZ compression unit</h3>
<p>Another good experiment about speed was writing and profiling our
<em>SynLZ</em> compression unit. With this optimized implementation of a
<a href="http://en.wikipedia.org/wiki/LZ77_and_LZ78">LZ-family</a> compression
algorithm, compression is up to 20 times faster than zip, decompression 3 times
faster. In fact, it competes with LZO for compression ratio and decompression
speed, but is much faster than LZO for compression: <em>SynLZ</em> is able to
compress the data at the same rate than it decompresses it. Such a symmetrical
implementation is very rare in the compression world.</p>
<p>It involves only integer arithmetic and bit logic, filling and lookup in
hash tables, and memory copy.</p>
<p>We wrote some very tuned pascal code, then compiled it with Delphi 7 and
Delphi 2009.</p>
<p>The Delphi 2009 generated code was faster than Delphi 7, in a noticeable
way. Generated code was indeed better, with better register reuse.</p>
<p>With hand-tuned assembler profiling, we achieved even better performance.
For instance, a 6 KB XML file is compressed at 14 MB/s using zip, 185 MB/s
using LZO, 184 MB/s using the Delphi 2009 pascal version of <em>SynLZ</em>, and
256 MB/s with our final tuned asm version of <em>SynLZ</em>.</p>
<h3>Conclusion</h3>
<p>For the generation of code involving integer process, text parsing or memory
, I think Delphi XE is faster than Delphi 7, but should be more or less at the
same level than Delphi 2007. Inlining was the main new feature, which could
speed up a lot the code.</p>
<p>But for real-world application, speed increase won't be noticeable. About 10
or 20% in some specific cases, not more. Algorithms is always the key to better
performance. Delphi 7 was already a nice compiler, handling dead code
elimination, clever register use and <a href="http://en.wikipedia.org/wiki/Peephole_optimization">peephole
optimization</a>.</p>
<p>For floating-point arithmetic, the Delphi compiler is nowadays deprecated.
For instance, the current Delphi compiler is <a href="http://delphimax.wordpress.com/2011/03/29/delphi-beaten-by-javascript">outperformed
by latest Javascript engines</a> using on the fly compilaton into SSE: you'll
have to code SSE by hand for acceptable results. I hope that SSE code in the
upcoming 64 bit compiler will change the results here. As far as
appears <a href="http://delphitools.info/2011/03/24/kudos-to-the-firefox-4-tracemonkey-team/comment-page-1/#comment-1528">in
this comment</a>, FPC 2.5.1 generated exe is already faster than Delphi
(similar to TraceMonkey, at least), because it handles SSE. Nice for an Open
Source compiler! :)</p>
<p><br />
Comments and feedback are <a href="http://synopse.info/forum/viewforum.php?id=12">welcome in our forum</a>!</p>How to unzip or zip files contenturn:md5:719ea8f136e28d890433c1622e285a862010-07-11T20:34:00+02:002010-07-11T20:34:00+02:00AB4327-GANDIOpen SourceblogcompressionDelphiSynopsezip<p>Didn't you ever wanted to unzip some archive content, or embed a zip file
into your exe?</p>
<p>Didn't you ever wanted to create a zip archive file, from some data in
memory, in pure Delphi code, without using any external dll?</p>
<p>One of the open source unit we use allow you to do these tasks in a easy
way.</p> <p>First of all, all the zip compression is embedded in an unique Delphi unit,
named SynZip which is meant to replace the default zlib unit of Delphi, and
enhance it. It works from Delphi 7 to Delphi 2010, from the same source code,
which is released under a GPL/LGPL/MPL tri-license.</p>
<p>Do you want to compress some data in memory? Use CompressString() and
UnCompressString() methods. Both work with RawByteString encoded data:</p>
<pre>
function test: boolean;<br />
var tmp: RawByteString;<br />
begin<br />
tmp := 'some data';<br />
result := (UnCompressString(CompressString(tmp,False,comp))=tmp);<br />
end;
</pre>
<p>Do you want to create a zip archive file? Use our TZipWrite class.</p>
<pre>
procedure TestCompression;<br />
var FN: TFileName;<br />
begin<br />
FN := ChangeFileExt(paramstr(0),'.zip');<br />
with TZipWrite.Create(FN) do<br />
try<br />
AddDeflated('one.exe',pointer(Data),length(Data));<br />
assert(Count=1);<br />
AddDeflated('ident.txt',M.Memory,M.Position);<br />
assert(Count=2);<br />
finally<br />
Free;<br />
end;<br />
end;
</pre>
<p>Do you want to read a zip archive file? Use our TZipRead class.</p>
<pre>
procedure TestUnCompression;<br />
var FN: TFileName;<br />
i: integer;<br />
begin<br />
FN := ChangeFileExt(paramstr(0),'.zip');<br />
with TZipRead.Create(FN) do<br />
try<br />
i := NameToIndex('ONE.exe');<br />
assert(i>=0);<br />
assert(UnZip(i)=Data);<br />
i := NameToIndex('ident.TXT');<br />
assert(i>=0);<br />
assert(Entry[i].info^.zcrc32=crc32(0,M.Memory,M.Position));<br />
finally<br />
Free;<br />
end;<br />
DeleteFile(FN);<br />
end;
</pre>
<p>And if you want the file to be embedded to your executable, there is a
dedicated Create constructor in the TZipRead just for handling that:</p>
<ol>
<li>create your exe file with a TZipRead instance created with it;</li>
<li>append your zip content to your exe (by using TZipWrite or by using copy /b
on command line);</li>
<li>that's all!</li>
</ol>
Couldn't it be easier?
<div><br />
<div>Code above was extracted and adapted from our SynSelfTests test
unit.</div>
<div>Comments and questions are welcome on <a href="http://synopse.info/forum/viewtopic.php?pid=163#p163">our forum</a>.</div>
</div>Pure pascal LZO and SynLZ compression unitsurn:md5:6d525e5bd5f022e96054324ab1c437212010-06-26T18:52:00+02:002011-06-06T11:01:03+02:00AB4327-GANDIOpen Source librariesblogcompressionDelphiSourcezip<p>In our Source Code repository you would have perhaps noted the
<em>SynLZ.pas</em> and <em>SynLZO.pas</em> units.</p>
<p>These are two in-memory compression units, optimized for speed.</p>
<p><em>SynLZ</em> is a brand new LempelZiv-based compression algorithm, the
fastest around for compression speed, so very suitable for using on Server
side, with very low CPU consumption.</p> <h2>SynLZO</h2>
<p>The <strong>SynLZO</strong> unit implements Synopse LZO Compression:</p>
<ul>
<li>it's an upgraded and fully rewritten version of our <a href="http://bouchez.info/lzo.html">MyLZO</a> unit;</li>
<li><em>SynLZO</em> is a very FAST portable loss-less data
compression library written in optimized pascal code for Delphi 3 up to Delphi
XE with a tuned <em>asm</em> version available;</li>
<li>offers *extremely* fast compression and decompression with good compression
rate, in comparaison with its speed;</li>
<li>original <a href="http://www.oberhumer.com/opensource/lzo/">LZO</a> written
in ANSI C - pascal+asm conversion by A.Bouchez;</li>
<li>simple but very fast direct file compression: <em>SynLZO</em> compressed
files read/write is faster than copying plain files!</li>
</ul>
<br />
<h2>SynLZ</h2>
<p>The <strong>SynLZ</strong> unit implements <em>Synopse LZO
Compression</em>:</p>
<ul>
<li> <em>SynLZ</em> is a very FAST lossless data compression library
written in optimized pascal code for Delphi 3 up to Delphi XE with a tuned
<em>asm</em> version available;</li>
<li> symmetrical compression and decompression speed (which is very
rare above all other compression algorithms in the wild);</li>
<li> good compression rate (same range than LZO);</li>
<li> fastest average compression speed (ideal for xml/text
communication, e.g.) - LZO is faster on decompression, but slower on
compression.</li>
</ul>
<br />
<p>Even if <em>SynLZO</em> is a pascal conversion of the LZO algorithm, the
<strong>SynLZ</strong> unit implements a <strong>new compression
algorithm</strong> with the following features:</p>
<ul>
<li> hashing+dictionary compression in one pass, with no <em>Huffman</em>
table;</li>
<li> optimized 32bits control word, embedded in the data stream;</li>
<li> in-memory compression (the dictionary is the input stream
itself);</li>
<li> compression and decompression have the same speed (both use
hashing);</li>
<li> thread safe and loss-less algorithm;</li>
<li> supports overlapping compression and in-place decompression;</li>
<li> code size for compression/decompression functions is smaller than
LZO's.</li>
</ul>
<p>SynLZ is used <em>e.g.</em> as the default compression algorithm for our
<a href="https://blog.synopse.info?post/category/Open-Source-Projects/SQLite3-Framework">ORM
framework</a> for Client - Server communication, resulting in very good
response time and bandwidth usage, especially with JSON content.</p>
<div>
<h2>Continue reading</h2>
<p>See <a href="http://synopse.info/forum/viewtopic.php?id=32">the
corresponding forum post</a> for details and comments</p>
</div>