7 ms·
Personally I think the notion that C++ offers "precise control" as you call it is overrated. For instance flexible memory allocation is touted as an advantage,
by cmbaus 13y ago
Personally I think the notion that C++ offers "precise control" as you call it is overrated. For instance flexible memory allocation is touted as an advantage, but in practice this is limited by the fact that there is only one global implementation of new the operator.
Over the long term I think Go is going to offer a much more sane environment for implementing high performance servers.
- mpyne 13y agoC++ does allow overriding the new operator, actually. It also allows for running just the constructor in an area of already-allocated memory, if you're particularly crazy. With that said it's hard to argue that Go makes concurrency easier at this point, which can certainly make it more useful for many of the types of problems programmers are seeing today.
- cmbaus 13y agoI realize this, but you can't provide multiple global implementations of new. It is difficult to implement multiple allocation strategies in the same application. In another time, I actually did quite a bit of work in this area: http://accu.org/index.php/articles/1308 http://accu.org/index.php/articles/1308
- mpyne 13y agoThat's true, but I'm not sure what it would even mean to have multiple implementations of the same function at the same time. Do you mean something like operator overloading where a given type has a different implementation of new that is used for it? Or a way to select different implementations of the global operator new at runtime? It seems to me that it should be possible for the latter to make it switchable, although the code would be inelegant to say the least. AFAIK the former is possible as well, but the problem is that I think the type-specific operator new/delete have to be members of the type which means that you can't add it on later. That's a great article btw.
- cmbaus 13y agoI'm going to dig deep here, and say that true flexibility in memory allocation would require multiple global implementations of new, and when an object is deleted it would be destroyed with an implementation of delete the corresponds with the implementation of new. That would be a gigantic change to the language, which I'm sure I don't understand the implications of. After thinking about this some more, I'm going to stand by my original, even if poorly argued, comment that C++ doesn't really live up to the promise of "precise control" when it comes to memory allocation, and this is one area that can have a big effect on performance. C++ has all the overhead of a low level language, with a promise of control that when you really need it is often difficult to access.
- coliveira 13y agoOk, so let's count... Just from the top of my head, we have global new/delete overloading. At the class level you have new/delete overriding. Then you have allocators that can be used with any STL container. In you templates you can also have custom allocators. Then you have new with placement syntax, which means that you can allocate memory with anything, including something like malloc or gmalloc. Of course, you can also use the stack for automatic memory... You can even use a garbage collector such as Boehm. And you really want to argue that there are no options for memory allocation in C++?... The problem with C++ is exactly the opposite, it has too many options, which makes it difficult to create a global memory management policy, unless you define you own complete framework. Quite the opposite of what you said.
- comex 13y agoI'm not sure whether the previous poster was thinking along these lines, but in some sense C++ makes it harder to control allocations compared to C due to a combination of increased abstraction and a general assumption that objects are fixed size. For example, if a C struct contains an array whose size is known at the time of allocation, there's a good chance the elements will be located after the end of the struct rather than being in a separate allocation. Of course, you could do this in C++, but neither language nor library provides sugar, so it ends up looking unnecessary compared to just using a std::vector. I won't opine on whether it actually is unnecessary.
- pcwalton 13y agoYou can just provide an allocate() static method and destroy() method on your object that use placement new and call the destructor manually. Or don't and just use placement new/manual destructor calling yourself. Are you trying to argue that C++ programs can't use custom allocators because of language restrictions? That's demonstrably false; Gecko and WebKit, just to name a couple of C++ codebases I'm relatively familiar with, use custom allocators everywhere.
- cmbaus 13y agoFair enough. My point was poorly made, and truthfully it has been along time since I've done significant C++ work. But it is difficult for the users of libraries like the STL to mix and match their allocation strategies, so for all practical purposes, most applications end up using the default implementation, or a single override of global new.
- coliveira 13y agoActually if you may create a policy for a particular type by implementing operator new at the class level. I think you're not well informed, because C++ is the language that gives you the most flexibility to design memory management schemes.
- maxlybbert 13y agoC++ allows both overriding (i.e., replacing) and overloading (i.e., creating multiple versions of) operator new. When overriding, you still have to call some memory allocation routine; and you should also override operator delete, and should probably override operator new[]/operator delete[]. There are some pitfalls in doing this on some platforms ( http://pavlovdotnet.wordpress.com/2008/01/12/jemalloc-builds/ http://pavlovdotnet.wordpress.com/2008/01/12/jemalloc-builds... ). The tricky part, to me at least, is when overloading. It's possible to overload new in a way that "new int" calls the original new, and "new int, foo" calls your overloaded allocator (foo could be an object used for the sole purpose of knowing which new to call, or it could actually be used by that new -- maybe it's a memory pool). That's easy enough to do. The surprise comes from the fact that while you can overload operator delete, it's a real pain to call the overloaded version (plus, of course, you have to remember which memory came from which version of new). Assuming you use "foo" to specify your overloaded new and delete, "delete p, foo" is a syntax error. You need to call something like "::operator delete(p, foo)". At least that was the case with C++03; I don't know if C++11 changed anything. Personally, I just overload new, but call a destroy() function instead of an overloaded delete.
- digikata 13y agoFor more flexible memory alloc in C++, can't one use placement new? That makes destruction more complicated, but maybe that's further support for the thought that complexity in C++ gives one more possibilities for precise control of the computing environment. How often one needs or wants to actually exercise that level control is another question. At any rate, Go certainly does offer some nice tradeoffs vs C++.
- fhd2 13y ago> Personally I think the notion that C++ offers "precise control" as you call it is overrated. For instance flexiblememory allocation is touted as an advantage, but in practice this is limited by the fact that there is only one global implementation of new the operator. I don't quite follow, who's stopping you from using sbrk(), mmap() and all the other low level allocation system calls if you really have to? AFAIK, many high performance applications have their own allocation mechanism. Furthermore, new/malloc is worlds apart from GC when it comes to precise memory management. Now, to be fair, I have no experience implementing high performance servers. But speaking for games, GC gets in the way a lot. You can make it work by essentially avoiding allocation altogether, at least on systems where you can use tons of memory, but that's just a very crude workaround.
- mpyne 13y ago> I don't quite follow, who's stopping you from using sbrk(), mmap() and all the other low level allocation system calls if you really have to? From a pure language perspective, nothing. From a standard library perspective... it's probably more difficult. I won't say impossible, as the STL allocator concept certainly seems general enough to allow this, but definitely more difficult.