This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]