This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
Re: lazy facet instantiation
On Nov 15, 2005, at 2:45 PM, Paolo Carlini wrote:
Howard Hinnant wrote:
Has the locale implementation technique of "lazy facet instantiation"
been kicked around? I searched the archive but came up empty. Imho
this is a critical technique for reducing the code size triggered by
casual use of C++ I/O.
[snip]
The idea sounds very cool, of course. However, at the moment I don't
fully understand where the *code size* (vs, application memory
footprint) reduction comes from, at least not from a quick glance
to our
locale from that point of view... Are you willing to explain in little
more detail?
Sure.
All of the facets are templated. Our current locale default
constructor (somewhere deep down under) does something like:
install(new ctype<char>);
install(new ctype<wchar_t>);
install(new codecvt<char,...>);
install(new codecvt<wchar_t,...>);
install(new num_get<char>);
... etc. ...
So just the act of default constructing a locale instantiates all of
the facets for all of the anticipated template parameters.
However if we instead of a locale default ctor that does nothing, and
instead wait to fill the locale on an as-needed basis under
use_facet<StandardFacet>(const locale&), then only those standard
facets which are actually retrieved via a use_facet get installed
into the locale. The standard facets not explicitly called via a
use_facet are not only not intalled into a locale, they aren't even
instantiated (assuming client code doesn't explicitly instantiate them).
For example, HelloWorld might use just ctype and codecvt (that's just
off the cuff, I'd have to study more to get a precise list). This
can cut the code size of HelloWorld (linked statically) by 80%.
It also affords one other really nice extension: With this
optimization a locale can contain a standard facet for an infinite
variety of templates. For example a locale would contain not only
ctype<char> and ctype<wchar_t>, but could also contain ctype<C>,
where C is any character-like type. Support for such extensions
allows clients to use basic_streams instantiated on types other than
char and wchar_t. All you have to do to use it is:
ctype<C>& ct = use_facet<ctype<C> >(some_locale);
(for some character-like type C). The ctype<C> facet is instantiated
*and* installed under the use_facet call.
This is a feature that both CodeWarrior and VC++ supports. People
want to do it, for example, when char is too small, and wchar_t is
too big, they sometimes:
basic_ostringstream<unsigned short> os;
-Howard