lmi
[Top][All Lists]
Advanced

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

Re: [lmi] testing actuarial_table performance


From: Greg Chicares
Subject: Re: [lmi] testing actuarial_table performance
Date: Thu, 31 May 2012 10:20:54 +0000
User-agent: Mozilla/5.0 (Windows NT 5.1; rv:10.0.2) Gecko/20120216 Thunderbird/10.0.2

On 2012-05-30 16:17Z, Václav Slavík wrote:
> On 30 May 2012, at 12:32, Greg Chicares wrote:
>> It's safe to assume that using xml tables will make the guideline-premium
>> server much slower. It runs only a single scenario at a time, and performs
>> only a small part of the illustration calculations. But that's not a big
>> enough concern to obstruct the goal of migrating to xml: that server is
>> not currently used in production; and it uses only a few small tables,
>> which could be hard-coded if we want (e.g., table_42() in the unit test
>> for tables is already hard coded, and adding a few dozen like it wouldn't
>> take much space).
> 
> If I understand it correctly, the server is a short lived process, correct?

Yes. It reads one input file and writes one output file. It was designed to
receive asynchronous input files from a client and send back output files.
But it's not used in production--so it's a use-case that may *inform* our
present work on xml tables, but doesn't *constrain* that work.

And it just so happens that this year I plan to do some major work on the
calculations that underlie that server, so this discussion is timely. For
instance, I wonder whether the "few small tables" mentioned above might
serve as a design prototype for the amalgamated tables that we envision
as encompassing gender and smoker variations.

I think the experimental patch in your 2012-05-29T13:23Z email resolves
the performance issue for the production system, so further performance
improvements are not urgently necessary--but are still worth considering.

> We could still cache the data on disk e.g. as a memory-mapped dump if the
> performance proves to be a problem.

I hesitate to venture too far beyond ISO-standard C++ or to add dependencies
on more libraries (such as boost::mapped_file). All lmi calculations (not
just the server mentioned above) are available through command-line programs
that don't depend on wx, so I don't want to introduce a dependency on a wx
implementation here.

Any OS we'd target probably uses memory-mapped IO for its process loader, so
couldn't we secure this advantage by compiling tables into a shared library,
and let the OS do memory-mapped IO implicitly? If that's a good approach,
then we'd certainly want to implement your next idea:

> Or at least automate the translation
> of XML actuarial table into corresponding C++ code ("hard coded table")...

If we do this, and put the generated code in a shared library, then we could
distribute one shared library instead of hundreds of files. (Actually, we'd
want two libraries: one for proprietary data, and one for nonproprietary.)
I think that would make distribution to end users easier and more reliable.

And if that's a good idea, then we might do the same for product-database
files ('.policy', '.database', etc.). Then we could remove the primitive
caching of those files (Input::CachedProductName_ etc.), which preserves
the contents of at most one most-recently-used '.database' file--and make
the production system faster, as well as easier to distribute. (Very few
users modify those files with the product editor, but any modification
would have to refresh or poison the cache).

> I can look into xmlwrapp performance too if you want.

Yes, I endorse that if you think it would be fruitful.

> I'll focus on fixing the performance first, then. The two obvious approaches 
> I can see are
> 
> (a) cache globally (as in this prelim. patch); or

A static std::map in a member function (your 2012-05-29T13:23Z email) seems
like a very good idea to me. (In this part:
        actuarial_table *t = new actuarial_table(filename, number);
        s_cache[key] = t;
        return *t;
is there a significant performance advantage to using pointers? Maybe I'm
just superstitious, but I worry that pointers can be invalid, so I try
really hard to avoid them. We don't have std::map::emplace() in libstdc++
even with gcc-4.7:
  http://gcc.gnu.org/onlinedocs/libstdc++/manual/status.html#status.iso.200x
but, until we have it, couldn't we insert a small dummy actuarial_table
object into the map and then swap() in the real one? or just let the copy
ctor be called, if it doesn't cost much?)

> (b) remove actuarial_table_rates*() functions, replace them with 
> actuarial_table
> method calls, managed lifetime of of actuarial_table instances in the callers
> 
> Do you have any preference? The first one is certainly much simpler and 
> maximizes
> "cache hits", but it never frees memory [1], but it's somewhat ugly compared 
> to (b).
> I didn't investigate this deeply enough to understand how doable (b) is.
[...]
> [1] Although this could be addressed with periodical pruning, of course.

I'm not sure I really understand (b), but I think I prefer (a) anyway.
Personally, I don't see any ugliness in (a), though maybe I'm missing
something. But the main point is that we can just keep the tables in
memory forever.

We have 541 proprietary '.xtable' files, totaling 23.5 MiB on disk;
the arrays of <double> we'd create from them must be even smaller.
The GUI version of lmi uses about 20-40 MiB of RAM already, and it
doesn't much matter if that becomes 40-60.



reply via email to

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