From: Dean M. B. <mik...@gm...> - 2010-11-22 10:32:24
|
Hi Everyone, A lot of people ask why cpp-netlib is header-only and whether there's a way to move some of the library out to externally linked libraries. It looks like the compile time is really a big hindrance to some people, which is starting to make me question the wisdom of why I'm actually fighting to keep cpp-netlib a header-only library. With that in mind I'm thinking about user-selectable means of installing the library. I'm thinking for some people having the library only in headers might be an option -- say, if they wanted to just distribute a single binary and they were only building a single .cpp file and wanted the compiler to be able to optimize everything, inline things worth inlining, etc. So I'm starting with cpp-netlib 0.9 to move some of the implementations out into .ipp files, and having struct declarations left out in the .hpp files. Now, I'm also looking at making some of the templates opaque types, so that some of the function implementations can be moved in .cpp files. The idea is, when cpp-netlib is used as a header-only library (which is the default case), everything necessary is brought in just like it is implemented now. However, if you use it with BOOST_NETWORK_NO_DEFINITIONS, then the .ipp's aren't included by the .hpp's and all the definitions should be compiled and linked in from an external shared/static library. The challenge now is breaking up all the template implementations and making some of the types opaque. Another technique that I would like to re-think is the tag-based metafunction dispatch. I think it's clever, and I definitely think it helps with hiding a lot of the complexity of the library. However, it looks like having a straight-forward policy-based design might even allow more people to develop more policies that can be made part of the library. The main push-back I'm getting with the library now is that it's taking a lot of resources to build just a simple example. This is a non-starter for a lot of people and I am willing to compromise on this given that I'm starting to see the larger picture. Basically, I'm going to move a lot of the static dispatch out from metafunctions, and just rely on policies for the client, server, and message implementations. The message type can be made opaque (a simple struct) which can then just play nicely with the concepts. This would remove a lot of the metafunctions that get instantiated all the time causing the huge compile time requirements. As much as I think the tag mechanism we're using is one of a kind and is really scalable conceptually, the reality is no current compilers can deal with the compile-time costs associated with the technique. Anyway, I'm getting a hang of writing these long update reports so I hope you bear with me as I go share more of my thoughts with everyone on the list. Let me know if you have any objections, whether you agree, and whether you know of a better way of doing things than what I suggest above. Thanks for reading and I definitely look forward to the feedback. Have a good one everyone and I hope to hear from you soon! -- Dean Michael Berris deanberris.com |
From: Glyn M. <gly...@gm...> - 2010-11-22 20:43:49
|
Hi Dean, On 22 November 2010 11:31, Dean Michael Berris <mik...@gm...>wrote: > Hi Everyone, > > A lot of people ask why cpp-netlib is header-only and whether there's > a way to move some of the library out to externally linked libraries. > It looks like the compile time is really a big hindrance to some > people, which is starting to make me question the wisdom of why I'm > actually fighting to keep cpp-netlib a header-only library. > > With that in mind I'm thinking about user-selectable means of > installing the library. I'm thinking for some people having the > library only in headers might be an option -- say, if they wanted to > just distribute a single binary and they were only building a single > .cpp file and wanted the compiler to be able to optimize everything, > inline things worth inlining, etc. > > So I'm starting with cpp-netlib 0.9 to move some of the > implementations out into .ipp files, and having struct declarations > left out in the .hpp files. Now, I'm also looking at making some of > the templates opaque types, so that some of the function > implementations can be moved in .cpp files. > I think this is a worthwhile task. I agree that we were being optimistic when we thought that build times / build size wouldn't matter. > > The idea is, when cpp-netlib is used as a header-only library (which > is the default case), everything necessary is brought in just like it > is implemented now. However, if you use it with > BOOST_NETWORK_NO_DEFINITIONS, then the .ipp's aren't included by the > .hpp's and all the definitions should be compiled and linked in from > an external shared/static library. > > Get this wrong and it could be a maintenance nightmare. Did you look into using precompiled headers? What was your conclusion? > The challenge now is breaking up all the template implementations and > making some of the types opaque. > > Another technique that I would like to re-think is the tag-based > metafunction dispatch. I think it's clever, and I definitely think it > helps with hiding a lot of the complexity of the library. However, it > looks like having a straight-forward policy-based design might even > allow more people to develop more policies that can be made part of > the library. > A policy-based design would suit the XMPP client much more naturally, IMO. Also, I think tag-based dispatch is overkill for the URI, since the only parameter it uses is a string. > The main push-back I'm getting with the library now is that it's > taking a lot of resources to build just a simple example. This is a > non-starter for a lot of people and I am willing to compromise on this > given that I'm starting to see the larger picture. > > Basically, I'm going to move a lot of the static dispatch out from > metafunctions, and just rely on policies for the client, server, and > message implementations. The message type can be made opaque (a simple > struct) which can then just play nicely with the concepts. This would > remove a lot of the metafunctions that get instantiated all the time > causing the huge compile time requirements. > > As much as I think the tag mechanism we're using is one of a kind and > is really scalable conceptually, the reality is no current compilers > can deal with the compile-time costs associated with the technique. > > Anyway, I'm getting a hang of writing these long update reports so I > hope you bear with me as I go share more of my thoughts with everyone > on the list. Let me know if you have any objections, whether you > agree, and whether you know of a better way of doing things than what > I suggest above. > > I agree. Tag-based dispatching is very powerful but we run up against a physical limit which will prevent adoption for anyone but the most enthusiastic generic programmer. G |
From: Dean M. B. <mik...@gm...> - 2010-11-23 07:28:43
|
On Tue, Nov 23, 2010 at 4:43 AM, Glyn Matthews <gly...@gm...> wrote: > Hi Dean, > > On 22 November 2010 11:31, Dean Michael Berris <mik...@gm...> > wrote: >> >> The idea is, when cpp-netlib is used as a header-only library (which >> is the default case), everything necessary is brought in just like it >> is implemented now. However, if you use it with >> BOOST_NETWORK_NO_DEFINITIONS, then the .ipp's aren't included by the >> .hpp's and all the definitions should be compiled and linked in from >> an external shared/static library. >> > > Get this wrong and it could be a maintenance nightmare. Did you look into > using precompiled headers? What was your conclusion? > I did look at precompiled headers and they're absolutely huge -- 250MB for the client and/or server. :( Just reading these files on traditional spinning disks, even mmap'ed just takes too long. Clang has a different style with precompiled headers, but the precompiled headers are absolutely huge as well. It may be that all the template information, though valuable, may be creating too many AST node representations in compiling. This might be because of Proto, Fusion, and Spirit, but given that we are using these libraries internally, I don't see making precompiled headers a good enough solution to this problem. Maybe abandoning the header-only approach might actually make the library better, and allow more developers to be able to contribute. I'm starting to think this header-only business doesn't really scale well. :( >> >> The challenge now is breaking up all the template implementations and >> making some of the types opaque. >> >> Another technique that I would like to re-think is the tag-based >> metafunction dispatch. I think it's clever, and I definitely think it >> helps with hiding a lot of the complexity of the library. However, it >> looks like having a straight-forward policy-based design might even >> allow more people to develop more policies that can be made part of >> the library. > > A policy-based design would suit the XMPP client much more naturally, IMO. > Also, I think tag-based dispatch is overkill for the URI, since the only > parameter it uses is a string. Yep. Unless the compilers improve tomorrow and suddenly deal with templates as though it was a real programming language embedded in C++ compilation, I don't see how this technique can be justified in terms of the compilation costs. >> >> Anyway, I'm getting a hang of writing these long update reports so I >> hope you bear with me as I go share more of my thoughts with everyone >> on the list. Let me know if you have any objections, whether you >> agree, and whether you know of a better way of doing things than what >> I suggest above. >> > > I agree. Tag-based dispatching is very powerful but we run up against a > physical limit which will prevent adoption for anyone but the most > enthusiastic generic programmer. Definitely. -- Dean Michael Berris deanberris.com |