On Fri, 17 Aug 2007, David Greene wrote:> Ah. Basically operator<< for FILE*. I don't see a lot of benefit to > redefining operator<< for every type just to avoid ostreams. The > problem isn't basic_ostream _per_se_. There are two issues we're > worried about:The problem is basic_ostream and the design of the whole iostreams library. Use of virtual base classes makes every virtual method particularly expensive, for example.> 1. The static constructor contortions in place to handle the extremely > unlikely case of a static object constructor writing to one of the > standard streams.I also dislike this strongly, but it isn't really related.> 2. Slowness of std::cout and friends due to their reliance on FILE * > buffering and resulting excessive virtual function calls.Use of FILE* is not the issue, virtual functions are.> I just implemented "standard" AsmStreams (the name for my custom streams) to > handle the cases where we want to dump Asm to standard error. I just point > the AsmStreambuf to STDERR_FILENO. I simply avoid the constructor issue by > declaring that no user shall write to an AsmStream in a static object > constructor. So we don't have worries about multiple constructor calls at > program startup. There is no ios_base::Init equivalent for AsmStream.This gives you the virtual overhead of streams without the buffering overhead of FILE*. Instead of the buffering overhead of stdio you have your own different but exactly equivalent buffering overhead.> The second concern is addressed as described earlier. I do the buffering > at the AsmStream level to minimize virtual calls.How is this different than buffering done by stdio?> This will still be slightly slower than raw FILE * or POSIX calls because > there will be some virtual function call overhead. But it should be much > better than standard streams and we get all of the nice benefits of iostreams.The only problem you seem to have solved is avoiding having to define a few operator<<'s, this doesn't seem like a very good tradeoff to me. -Chris -- http://nondot.org/sabre/ http://llvm.org/
On Friday 17 August 2007 17:01, Chris Lattner wrote:> On Fri, 17 Aug 2007, David Greene wrote: > > Ah. Basically operator<< for FILE*. I don't see a lot of benefit to > > redefining operator<< for every type just to avoid ostreams. The > > problem isn't basic_ostream _per_se_. There are two issues we're > > worried about: > > The problem is basic_ostream and the design of the whole iostreams > library. Use of virtual base classes makes every virtual method > particularly expensive, for example.I don't know about "particularly." The performance loss of virtual functions is mostly due to lack of inlining. Once that's gone, a pointer adjustment here or these isn't going to matter much.> > 1. The static constructor contortions in place to handle the extremely > > unlikely case of a static object constructor writing to one of the > > standard streams. > > I also dislike this strongly, but it isn't really related.Isn't this the motivation behind "#include <iostreams> is hereby FORBIDDEN?"> > 2. Slowness of std::cout and friends due to their reliance on FILE * > > buffering and resulting excessive virtual function calls. > > Use of FILE* is not the issue, virtual functions are.To some degree. I'd say the bigger issue is that libstdc++-v3 has put the buffering behind the virtual calls, causing many more virtual calls than necessary. This is a direct consequence of using FILE *.> This gives you the virtual overhead of streams without the buffering > overhead of FILE*. Instead of the buffering overhead of stdio you have > your own different but exactly equivalent buffering overhead.What "overhead" are you talking about, specifically? I'm not sure what you're getting at here. All buffering necessarily has some overhead.> > The second concern is addressed as described earlier. I do the buffering > > at the AsmStream level to minimize virtual calls. > > How is this different than buffering done by stdio?It's in front of the virtual calls. So you only invoke virtual calls when the buffer is full. At that point, you're writing to the file cache at best or to disk at worst (or is that to the network?). A virtual call seems a small price to pay for the flexibility it provides.> > This will still be slightly slower than raw FILE * or POSIX calls because > > there will be some virtual function call overhead. But it should be much > > better than standard streams and we get all of the nice benefits of > > iostreams. > > The only problem you seem to have solved is avoiding having to define a > few operator<<'s, this doesn't seem like a very good tradeoff to me.It's more than a few. Do a "grep 'operator<<'" in your C++ standard include directory. Arguably we don't need all of those, but we'll need a lot of them. It also means developing new manipulators and possibly locale support if we want to use it for error messages and the like. What you're talking about is developing a new C++ I/O library, which is certainly a worthy goal, but one I'm not being paid to achieve. :) If someone wants to take on this larger project, there would be many in the C++ community who would be interested in helping. The Boost folks, for example, have been talking about I/O designs for a couple of months now. -Dave
>>> 1. The static constructor contortions in place to handle the >>> extremely >>> unlikely case of a static object constructor writing to one of the >>> standard streams. >> >> I also dislike this strongly, but it isn't really related. > > Isn't this the motivation behind "#include <iostreams> is hereby > FORBIDDEN?"Yes it is. As I said, I don't like this aspect of the standard streams, but it isn't very related to this problem.>>> 2. Slowness of std::cout and friends due to their reliance on FILE * >>> buffering and resulting excessive virtual function calls. >> >> Use of FILE* is not the issue, virtual functions are. > > To some degree. I'd say the bigger issue is that libstdc++-v3 has > put the > buffering behind the virtual calls, causing many more virtual calls > than > necessary. This is a direct consequence of using FILE *.How so? It's entirely possible to use FILE*'s without virtual methods: just don't use iostreams.>> This gives you the virtual overhead of streams without the buffering >> overhead of FILE*. Instead of the buffering overhead of stdio you >> have >> your own different but exactly equivalent buffering overhead. > > What "overhead" are you talking about, specifically? I'm not sure > what you're > getting at here. All buffering necessarily has some overhead.Buffering has overhead from copying data around. It doesn't matter whether you do in by using stdio buffering or by building your own buffers to avoid virtual method overhead.>>> The second concern is addressed as described earlier. I do the >>> buffering >>> at the AsmStream level to minimize virtual calls. >> >> How is this different than buffering done by stdio? > > It's in front of the virtual calls. So you only invoke virtual > calls when the > buffer is full. At that point, you're writing to the file cache at > best or to > disk at worst (or is that to the network?). A virtual call seems a > small > price to pay for the flexibility it provides.How is that different than stdio?>>> This will still be slightly slower than raw FILE * or POSIX calls >>> because >>> there will be some virtual function call overhead. But it should >>> be much >>> better than standard streams and we get all of the nice benefits of >>> iostreams. >> >> The only problem you seem to have solved is avoiding having to >> define a >> few operator<<'s, this doesn't seem like a very good tradeoff to me. > > It's more than a few. Do a "grep 'operator<<'" in your C++ > standard include > directory. Arguably we don't need all of those, but we'll need a > lot of them.You only need to define the ones you need, and can do it over time.> It also means developing new manipulators and possibly locale > support if > we want to use it for error messages and the like.Manipulators and locales are two other really ugly things of iostreams :)> What you're talking about is developing a new C++ I/O library, > which is > certainly a worthy goal, but one I'm not being paid to achieve. :)Fair enough. -Chris