[netlib] Update: 0.9 will not be header-only

Hi Everyone, To those who are following the development of cpp-netlib (which shall be submitted for review /soon/ as Boost.Netlib), the current state of 0.9-devel and thus what's going to come out officially as 0.9 in a couple of weeks, will not be header-only. Aside from the obvious reason that the compile-times are starting to become unbearable (>10 minutes to build the whole test suite!!) and after noticing that the intended simplicity of the API with tag-metafunction dispatch is limiting the expressiveness of the HTTP client types, the 0.9 release will be the first release that will require an externally linked-in static library. The biggest culprit at the moment has been the implementation of the URI parser that uses Boost.Spirit Qi and >10 rules in the URI parsing grammar. The URI implementation is really declarative and nicely written (thanks go out to Jeroen Habraken for making that happen). The down-side of this has been the compile times: building the simple HTTP client takes close to one minute on the machine I'm using -- and by moving it to an externally-linked static lib, the compile of the same HTTP client is cut down to 10 seconds. Before you ask if I'm using GCC, the answer is no, I'm using Clang when developing so that I get as much speed as I can when doing the edit-rebuild-test cycle. I've written about what I've been doing and what I'll be doing in my three recent articles at C++ Soup. If you want to get more details, please follow the links below. http://cplusplus-soup.com/2010/12/03/cpp-netlib-moving-away-from-header-only... http://cplusplus-soup.com/2010/12/02/cpp-netlib-demolition-day/ http://cplusplus-soup.com/2010/12/01/cpp-netlib-reducing-compilation-times/ Have a great weekend everyone, please send your qestions/comments/suggestions over either directly to me or through the various mailing lists (Boost-devel, Boost-users, cpp-netlib-devel). -- Dean Michael Berris deanberris.com

On 12/3/2010 8:45 AM, Dean Michael Berris wrote:
To those who are following the development of cpp-netlib (which shall be submitted for review/soon/ as Boost.Netlib), the current state of 0.9-devel and thus what's going to come out officially as 0.9 in a couple of weeks, will not be header-only.
Dean - I am happy to hear the change. One of my main reasons for not investigating the library further after boostcon was the intent to keep it header only "come hell or high-water". I know there are polarized opinions on the subject of header-only and I have no intent to start that thread again. Just wanted to voice my support for the move to using the linker when it makes sense. Thank you for the hard work you have put into the library and I am looking forward to the 0.9 release. Take care - Michael btw ... I have http header parsers/generators written in Qi/Karma. If you are looking for those bits let me know. -- ---------------------------------- Michael Caisse Object Modeling Designs www.objectmodelingdesigns.com

On Dec 3, 2010, at 4:50 PM, Michael Caisse wrote:
btw ... I have http header parsers/generators written in Qi/Karma. If you are looking for those bits let me know.
I do! I have the general MIME parser blocked out (and mostly working). Adding parsers for specific headers is on my to-do list. -- Marshall

On 12/4/2010 12:45 AM, Dean Michael Berris wrote:
The biggest culprit at the moment has been the implementation of the URI parser that uses Boost.Spirit Qi and>10 rules in the URI parsing grammar. The URI implementation is really declarative and nicely written (thanks go out to Jeroen Habraken for making that happen). The down-side of this has been the compile times: building the simple HTTP client takes close to one minute on the machine I'm using -- and by moving it to an externally-linked static lib, the compile of the same HTTP client is cut down to 10 seconds. Before you ask if I'm using GCC, the answer is no, I'm using Clang when developing so that I get as much speed as I can when doing the edit-rebuild-test cycle.
Ouch! :P What the compiler giveth, Spirit taketh. It's time we do something about it. Regards, -- Joel de Guzman http://www.boostpro.com http://spirit.sf.net

On 12/3/2010 7:58 PM, Joel de Guzman wrote:
On 12/4/2010 12:45 AM, Dean Michael Berris wrote:
The biggest culprit at the moment has been the implementation of the URI parser that uses Boost.Spirit Qi and>10 rules in the URI parsing grammar. The URI implementation is really declarative and nicely written (thanks go out to Jeroen Habraken for making that happen). The down-side of this has been the compile times: building the simple HTTP client takes close to one minute on the machine I'm using -- and by moving it to an externally-linked static lib, the compile of the same HTTP client is cut down to 10 seconds. Before you ask if I'm using GCC, the answer is no, I'm using Clang when developing so that I get as much speed as I can when doing the edit-rebuild-test cycle.
Ouch! :P What the compiler giveth, Spirit taketh. It's time we do something about it.
It would probably pay to start by running Steven's template profiler on Dean's URI parser. Let's see who's instantiating all those templates. I think much can be done in both Proto and Fusion to speed things up. In particular, I'd like Proto to do what MPL does with the preprocessed headers. Fusion could probably do the same. Who wants to help? :-) In the mean time, I HIGHLY recommend precompiled headers for bringing down compile times for TMP-heavy libraries like Spirit and xpressive. -- Eric Niebler BoostPro Computing http://www.boostpro.com

On 04/12/10 07:29, Eric Niebler wrote:
I think much can be done in both Proto and Fusion to speed things up. In particular, I'd like Proto to do what MPL does with the preprocessed headers. Fusion could probably do the same. Who wants to help? :-) Last time we spke of this, IIRC heller was about to have a look.

joel falcou wrote:
On 04/12/10 07:29, Eric Niebler wrote:
I think much can be done in both Proto and Fusion to speed things up. In particular, I'd like Proto to do what MPL does with the preprocessed headers. Fusion could probably do the same. Who wants to help? :-) Last time we spke of this, IIRC heller was about to have a look.
Correct ... I want to do this for months now ... haven't find the time yet. If someone wants to do it first, it would be great. The basic idea is to use wave as the preprocessor and use waves output pragma to "unroll" the Preprocessor iterations. Once the initial step has been done, it should be quite easy for other libraries to adapt to this preprocessing technique. The reason why I did not want to reuse the facilities developed for mpl is that the perl skript seems to be tailored just for mpl's use. IMHO, the effort to generalise this to enable preprocessing for other boost (or non boost) libraries is too high, compared to the effort of defining some wave specific macros.

Joel de Guzman wrote:
On 12/4/2010 12:45 AM, Dean Michael Berris wrote:
The biggest culprit at the moment has been the implementation of the URI parser that uses Boost.Spirit Qi and>10 rules in the URI parsing grammar. The URI implementation is really declarative and nicely written (thanks go out to Jeroen Habraken for making that happen). The down-side of this has been the compile times: building the simple HTTP client takes close to one minute on the machine I'm using -- and by moving it to an externally-linked static lib, the compile of the same HTTP client is cut down to 10 seconds. Before you ask if I'm using GCC, the answer is no, I'm using Clang when developing so that I get as much speed as I can when doing the edit-rebuild-test cycle.
Ouch! :P What the compiler giveth, Spirit taketh. It's time we do something about it.
Hmmmm - I'm not so sure. I've always found spirit compilation times to be very, very long. Even it were reduced to just very long they would be "too long". The real solution is just isolating them into something that is only compiled once - i.e. a library or DLL. Then the compilation time is a non-issue. Robert Ramey
Regards,

In my own experience, problem lies in Proto/MPL/Fusion preprocessor time more than anything else. MPL became managable thansk to the preprocessed headers, maybe Fusion,Proto and maybe Spirit should do the same

On Sun, Dec 5, 2010 at 2:02 AM, joel falcou <joel.falcou@lri.fr> wrote:
In my own experience, problem lies in Proto/MPL/Fusion preprocessor time more than anything else. MPL became managable thansk to the preprocessed headers, maybe Fusion,Proto and maybe Spirit should do the same
+1 Does anybody have an idea on how this can be done? I seem to recall that GCC only had options for preprocessing when compiling an object file -- that would mean for making a .cpp file for each of the headers that need to be pre-processed independently, running it through the compiler's preprocessor (or wave) to get the appropriate output. Maybe someone already has a script to do that which can be adapted? -- Dean Michael Berris deanberris.com

Dean Michael Berris wrote:
Hi Everyone,
To those who are following the development of cpp-netlib (which shall be submitted for review /soon/ as Boost.Netlib), the current state of 0.9-devel and thus what's going to come out officially as 0.9 in a couple of weeks, will not be header-only. Aside from the obvious reason that the compile-times are starting to become unbearable (>10 minutes to build the whole test suite!!) and after noticing that the intended simplicity of the API with tag-metafunction dispatch is limiting the expressiveness of the HTTP client types, the 0.9 release will be the first release that will require an externally linked-in static library.
Just happened to catch this. As a fan for all inline code and having made my own mistake not being aggressive enough with date-time, I say why not make it a configurable option? That way the client code can decide depending on their project structure. Even though I'm well versed in building boost libs I still love it when I don't have to be bothered. Inevitably, I'm working on some project and then I have to shift contexts, get bjam on the machine, include the new lib, etc when I already had that setup for the custom code I'm working. And besides, it's possible that some of us are using external tricks like pre-compiled headers that will reduce compile times. So, you might have something like this #include <boost/netlib_inline.h> versus #include <boost/netlib.h> to control the option. Or, of course, you could go with compiler macros/settings. Bottom line is that you can setup your test suite to use the library so that compile times are fast while still allowing all-inline for the rest of us. Jeff

On Sat, Dec 4, 2010 at 11:42 PM, Jeff Garland <jeff@crystalclearsoftware.com> wrote:
Dean Michael Berris wrote:
Hi Everyone,
To those who are following the development of cpp-netlib (which shall be submitted for review /soon/ as Boost.Netlib), the current state of 0.9-devel and thus what's going to come out officially as 0.9 in a couple of weeks, will not be header-only. Aside from the obvious reason that the compile-times are starting to become unbearable (>10 minutes to build the whole test suite!!) and after noticing that the intended simplicity of the API with tag-metafunction dispatch is limiting the expressiveness of the HTTP client types, the 0.9 release will be the first release that will require an externally linked-in static library.
Just happened to catch this. As a fan for all inline code and having made my own mistake not being aggressive enough with date-time, I say why not make it a configurable option? That way the client code can decide depending on their project structure. Even though I'm well versed in building boost libs I still love it when I don't have to be bothered. Inevitably, I'm working on some project and then I have to shift contexts, get bjam on the machine, include the new lib, etc when I already had that setup for the custom code I'm working. And besides, it's possible that some of us are using external tricks like pre-compiled headers that will reduce compile times.
Making it a compile time option would be a good choice. I thought about it through the weekend and how I would like to go about doing it and I think I might come with a good enough solution soon. I tried out the precompiled headers with GCC, and unfortunately the resulting precompiled headers are absolutely huge -- for including the HTTP client and all required facilities that come with it, it amounts to 248MB while the server implementation takes around 256MB. Just reading those into memory is a problem enough for the compiler. I haven't been able to see how big the precompiled headers turn out in MSVC, and it might be something worth looking into. However, that only solves part of the problem because since everything in the header-only version of cpp-netlib is a template (function or type), that still means that the compiler has to go through all the instantiations to come out with the proper IR/binary.
So, you might have something like this
#include <boost/netlib_inline.h>
versus
#include <boost/netlib.h>
to control the option. Or, of course, you could go with compiler macros/settings. Bottom line is that you can setup your test suite to use the library so that compile times are fast while still allowing all-inline for the rest of us.
Thanks for the suggestion, the only issue with that is the potential maintenance problem that would pose for us working on the library and supporting users that might use the inlined version and users using the non-inlined version. At the end of the day though having a choice is better than not having a choice at all. :) I'll spend time today to get back into making the changes necessary to make the library non-header only for those who want it non-header-only while allowing an option for making it header-only. I'll seek inspiration from other projects that have that option as well and I'll see how far that goes for me. :D Have a great day and thanks for the suggestions. :) -- Dean Michael Berris deanberris.com
participants (9)
-
Dean Michael Berris
-
Eric Niebler
-
Jeff Garland
-
Joel de Guzman
-
joel falcou
-
Marshall Clow
-
Michael Caisse
-
Robert Ramey
-
Thomas Heller