lmi
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [lmi] PDF generation performance


From: Greg Chicares
Subject: Re: [lmi] PDF generation performance
Date: Wed, 7 Feb 2018 22:31:32 +0000
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.5.2

On 2018-02-07 20:40, Vadim Zeitlin wrote:
> On Wed, 7 Feb 2018 15:34:53 +0000 Greg Chicares <address@hidden> wrote:
> GC> [...] End users will see this project as doubling the speed of
> GC> a noticeably time-consuming operation. It's not crucial to spend
> GC> time looking for microscopic refinements that might secure a
> GC> slightly greater improvement.
> 
>  I think it should be possible to obtain much more than microscopic
> refinements.

Big improvements are worthwhile.

> not exactly news that throwing exceptions and stack unwinding is very
> expensive in C++, but I was yet again surprised by just how bad it is

Will moving from 32- to 64-bit binaries remove most of that penalty,
at least for binaries built with MinGW-w64? For that compiler, IIRC
  64-bit binaries use SEH, the "Table" approach below
  32-bit binaries use SJLJ, the "Code" approach below (for C++,
    they're forced to: DW2 doesn't work, and SEH is not offered)

This paper is old (2006), but I don't imagine anything's changed much:

http://www.open-std.org/jtc1/sc22/wg21/docs/TR18015.pdf

5.4.1.1.2 Time Overhead of the �Code� Approach
| code unrelated to error handling is slowed down by the mere
| possibility of exceptions being used

5.4.1.2.2 Time Overhead of the �Table� Approach

| Unless an exception is thrown, no run-time overhead is incurred. 
| ... However, because of the need to examine potentially large
| and/or complex state tables, the time it takes to respond to an
| exception may be large, variable, and dependent on program size
| and complexity.

And I believe, or at least strongly hope, that nothing in lmi or
its libraries uses C++ exceptions as a control construct--i.e.,
that exceptions are thrown only when something goes wrong.

>  I won't work on this right now if you think it's not worth it, but I
> remain convinced that it should be possible to speed this up by a factor
> of multiple times even without introducing parallel processing. Just for
> the record, one idea which should almost certainly pay off would be to
> rewrite Ledger::make_evaluator() to produce values on demand as this
> functions takes more than half of the total time and creates a huge amount
> of strings which are never used.

We want to release the new PDF implementation into production in, say,
the first half of this year, and I'm not sure we want to be testing a
moving target. OTOH, I haven't begun to review Ledger::make_evaluator(),
and it takes less time to review an improved version of it once than to
review today's version soon and then an improved version later. And, on
the same "other hand", if we can figure out how to build more unit and
regression tests, all improvements become cheaper to accept.

>  But even without neither introducing threads nor making such architectural
> changes, I _still_ think we could find big efficiency gains here. For
> example, make_evaluator() seems to be so slow mostly because it uses
> ledger_format() which creates a new std::locale object for each call to it
> and this is a horrible expensive operation. Replacing it with a less
> elegant but faster implementation should help a lot.

At the risk of pontificating without even glancing at the code, I'm
inclined to doubt that caching locales would be inelegant.

>  Are you sure you don't want me to look at doing at least this?
It's clearly worthwhile. The "acceptance" phase of development is
always slow, because it takes a lot of work to convince ourselves
that we're as close to zero defects as we can be; therefore, I'd
suggest we work on testability enhancements before performance
enhancements. I'll delve into your unit-test proposal very soon.
As for system testing, let me send a new message to reopen a
recent thread.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]