Note for subscribers: if you are interested in my financial articles only, you can use this RSS feed link.
An uptick coming out of nowhere (except perhaps due to the traction of cryptocurrencies, coming out of nowhere as well!)
Note for subscribers: if you are interested in my financial articles only, you can use this RSS feed link.
An uptick coming out of nowhere (except perhaps due to the traction of cryptocurrencies, coming out of nowhere as well!)
Home page: | http://gen-img-dec.sf.net/ |
Project page: | http://sf.net/projects/gen-img-dec/ |
Mirror: | https://github.com/zertovitch/gid |
Alire crate: | https://alire.ada.dev/crates/gid |
Recent additions to the library are:
There are also two new tools shipped with GID (and of course using it):
Let's develop on the latter tool - the benchmarking program.
Each test image (they are all included in the repository) is decoded to a simple, "flat" bitmap format (PPM) and saved as a file, once using GID, once using ImageMagick.
Since GID is used internally by the benchmarking program and ImageMagick is used through a system call, we compensate for the time penalty of the external calls with the following technique:
We time many "empty" calls to ImageMagick that do only display some general information.
The resulting estimated "empty call" time is subtracted to the measured times of ImageMagick decoding the test images.
Then we have a fairer comparison.
The test machine is a HP ProDesk 400 G6 SFF with an Intel i7-9700 3 GHz processor running Window 10.
The Ada compiler used is GCC version FSF 11.2.0.
The GNAT compilation mode was set to Fast_unchecked for the benchmarking.
The version of ImageMagick is 7.1.1-27.
Here are the main results:
Format | Result |
---|---|
GIF | GID is 2.8 times faster (*) |
PNG | GID is 1.4 times faster |
JPEG Baseline | GID is 1.2 times faster |
JPEG Progressive | ImageMagick (as if internally called) is 1.9 times faster |
(*) It is not a typo: it is really written "2.8 TIMES faster", and not something like "2.8 percents faster".
Regarding the last format (JPEG Progressive), its GID implementation is only a few weeks old, translated from an implementation that is not conceived for performance but for helping understanding the format's mechanics. So it is not too surprising that it is significantly slower.
But the real surprise is with the losslessly compressed formats (GIF and PNG).
For those formats, GID is significantly faster than ImageMagick, despite the fact that a lot more effort is put in developing the ImageMagick library.
So, where does the miracle come from?
It comes from the Ada language. The generics mechanism in Ada is incredibly powerful, but you really begin to realize that only when using this construct.
Not surprisingly, GID has lots of generics: the keyword appears 30 times in the project, and of course always for a good reason.
Due to the nesting possibilities of Ada (subprogram within another, package within a subprogram, and so on; plus: generic entity within another one, or within a non-generic entity, which can itself be within a generic) and the possibilities of having formal generic parameters (the unknowns of the generics) begin used directly or indirectly for instantiating another generic, you get incredible code optimization possibilities. It sounds complicated, but actually it is very intuitive. You program these things easily without thinking to the actual implications that make the poor compiler sweat...
Regarding an image decoder like GID, the optimization challenge is always the same: when there is a choice (subformat, color space, etc.) that is invariant across the entire image, or large parts of it, you don't want your program to spend time testing for that choice at each pixel or each decoding point.
The reason is not only because of the time consumed by the test instructions themselves, but also the execution branches that slow down the predictive execution on modern processors.
Thanks to generics, you still can keep the "if" or "case" statements at their obvious places (sometimes close to the pixel output), but set the invariant as a generic formal parameter.
The compiler will eliminate the branches (the "if"'s or "case"'s) on specialized instantiations, because it knows, for example, that it is compiling a variant of a certain format that is progressive, with 8-bit per base color, with a certain color space, and that the final image is meant to be rotated by 270°.
We will relate on this technique of "optimization by generics" in a further article.
Another killer Ada feature used by GID is its extreme portability.
We don't need any source preprocessing in GID, although it is a very low-level library.
The consequence is a tremendous reduction of programming effort.
Let's show in a table some key points:
GID | ImageMagick (to date) | |
---|---|---|
People | 1 developer, much more active on other projects than GID, plus 1 developer for a one-shot contribution to the GIF format |
156 developers, on GitHub only. (Not counting 83 people of libpng, on GitHub only. Plus others folks for libjpeg...) |
Active since | 2010 | 1987 |
Portability | Unlimited (∞). All you need is a compiler supporting 32-bit integers. In doubt, GNAT will do the job... |
Each port (for a new processor or a new Operating System) seems to require a significant effort. |
Conditionals | Zero (0) | 113 #ifdef, 303 #ifndef, 573 #undef (!) |
Language | Ada | C |
Surely the word "deliverability" has a meaning in a certain context, but we don't care at all: it is a shiny, catchy word and thus a candidate for our Bullshit Generator, which is by essence contextless.
Let's test the new word with the "bulk" option added by Ludovic Brenta to the Generator.
produce_corporate_bullshit -b deliverability
Result: an endless logorhea (around 2000 lines of business-speak per second).
A few gems:
But the fun only begins at this point. Search one of those sentences with you preferred search engine!
Note for subscribers: if you are interested in my Ada programming articles only, you can use this RSS feed link.
The PayPal activity reports are simple, but a human being still needs some efforts to sort out their information.
When money is going out of your balance for, say, various kinds of fees, it is simple: one row... except if the fees are in a different currency. Then it is three rows, with different currencies - don't try to add those figures!
When money is going in, it can be a bit more complicated: the sum x is added, then immediately subtracted ("General Hold"), then, after days, added again ("General Hold Release"). If (just a thought experiment) the amount x is also locked for the sender of the payment, well, times 400 millions users, it might make a nice pile of short-term cash for PayPal (and interests to pocket)!
Back to our problem: all in all, the raw PayPal report is a mess (albeit, a correct one).
To untangle a report in a simple way (inserting the data into a database would be overkill in our usage), an appropriate tool to consider is Excel Writer (home page, svn repo, git repo) and Ada Containers' ordered sets. The resulting PayPal application is now part of the Excel Writer demos. Actually, we just had to derive the csv2xls tool/demo and plug the per-currency grouping.
Here is the messy PayPal report in CSV format, imported into LibreOffice:
Click to enlarge |
...and the formatted report, grouped by currency, in Excel format, here previewed by LibreOffice:
Click to enlarge |
Note for subscribers: if you are interested in my Ada programming articles only, you can use this RSS feed link.
The puzzle: https://adventofcode.com/2023/day/10
My Ada solution: here.
In a picture (generated by the program linked above)...
Click to enlarge |
It is always a pleasure to display the data created by Eric Wastl.
Here, an improved representation with the five cases (outside tile, inside tile, inside pixel on a path tile, outside pixel on a path tile, path pixel) in shown different colors:
Click to enlarge |
Note for subscribers: if you are interested in my financial articles only, you can use this RSS feed link.
A few charts without comments.
Note for subscribers: if you are interested in my Ada programming articles only, you can use this RSS feed link.
LEA, the Lightweight Editor for Ada, is based on the Scintilla text editor widget, which excels at colouring syntactic elements and letting the user rework his or her programs very swiftly, including manipulating rectangular selections and adding text on multiple points (usually vertically aligned).
But until recently, the cool features were limited to automatic indentation, adding comment delimiters (--) at the right column, or highlighting portions of text that match a selection.
Users were frustrated by not finding in LEA programming helpers (commonly grouped under the term "smart editor" or "intellisense") that they enjoy in their programming "studios".
An excuse would have been to dismiss such features as out of the scope of a "lightweight" editor.
But we know we can make of LEA a powerful mini-studio, with the ease of use of a simple editor, thanks to its "projectless" mode and the integrated HAC compiler.
So now, it happened.
From revision 385 of LEA (and revision 886 of HAC), you have now a good sense of intellisense:
Some screenshots will help illustrate the above points. Let's start with the sudoku_sample.adb example shipped with the HAC project. What's that "Sudo_Strings" type, for instance?
Just let the mouse pointer hang out around an occurrence of that keyword.
Mouse hover tip - Click image to enlarge it |
Go to declaration - Click image to enlarge it |
Declaration in the Sudoku package - Click image to enlarge it |
Call tip - Click image to enlarge it |
Auto-complete - Click image to enlarge it |
In order to develop the last point, here are a few examples on how LEA understands your program "on the fly", while you are typing it:
Smart editor on an incomplete piece of code - Click image to enlarge it |
Smart editor on an incomplete piece of code, sample 2 - Click image to enlarge it |
Smart editor on an incomplete piece of code, sample 3 - Click image to enlarge it |
Some Web links:
LEA
Web site: http://l-e-a.sf.net/
Sources, site #1: https://sf.net/p/l-e-a/code/HEAD/tree/
Sources, site #2: https://github.com/zertovitch/lea
Alire Crate: Alire - LEA
Web site: https://hacadacompiler.sourceforge.io/
Sources, site #1: https://sf.net/p/hacadacompiler/code/HEAD/tree/
Sources, site #2: https://github.com/zertovitch/hac
Alire Crate: Alire - HAC
Enjoy!
Note for subscribers: if you are interested in my financial articles only, you can use this RSS feed link. An uptick coming out of nowh...