MFC vs STL containers
-
I generally like the STL container classes, but since most of my code is with MFC, I generally just use its container classes. Doesn't everyone? Isn't using STL under MFC sort of a waste of effort? Or am I just out to lunch on that?:confused:
-
I'm kindof(CLazyObj) and I should use STL containers, but rely heavily on MFC containers. Are there any good books, docs or sites demonstrating STL containers? Norm
"STL tutorial and reference guide", by Musser and Saini ISBN 0-201-63398-1 -- Alex Marbus www.marbus.net But then again, I could be wrong.
-
I generally like the STL container classes, but since most of my code is with MFC, I generally just use its container classes. Doesn't everyone? Isn't using STL under MFC sort of a waste of effort? Or am I just out to lunch on that?:confused:
(0) I use STL these days. Reasons, off-hand... (i) STL has great support for virtually all the important data structures and algorithms you are ever likely to run into (e.g. multimap, multiset, function objects), unlike MFC containers. (ii) Most MFC containers (perhaps all--haven't used them for a while now) carry the built-in CObject support for serialization, debug dumping. Thus they hookup into MFC's global static data, and can be a great help for detecting mem leaks, etc. (iii) MFC is better, I guess, for beginners due to its clear separation of argument type and access type. But typing-in two things again and again quickly becomes a boredom... (iv) Unless you typedef, typing boredom will catch you faster than you thought in STL too :) A few underlying diffs, thrown together randomly: (vi) MFC CMap uses hashtable, STL map and many others, including set, use a tree. Thus retrieval time of stored objects is data-*value* dependent in CMap. The retrieval is guarunteed to be in logarithmic time for STL map. (Not sure if STL's is a threaded tree--could someone please clarify?) Implication: If your data is peculiar (a very very unlikely scenario) CMap *can* be faster than STL map. Implication: STL map always delievers on the fastest possible search time for random data. (vii) MFC CMap computes hash after casting to DWORD any key value. This means it computes hash on the address of const char*, but not on the whole null terminated C string *contents*, as you might expect. (That's a potentially dangerous situation--and therefore CTypedPtrWhateverTheGoodName is better there--it reminds you of what you key type there really is). At least CMap used to do so in version that shipped with VC++ 4, and I haven't checked the internals of CMap since then. Pl. correct me if I am off-tracks here. STL map (and many many other STL containers) *copy* the object of the generic parameter T. Due to the underlying tree, if you are going to store structs by value, you must supply a copy ctor and a global < operator to let STL find the right place to put your data as the leaf. Copy overheads need to be considered. (viii) There may be certain (rare) times when you are better off not using either MFC or STL. Mostly performance related. As one example: Why bother with either if you know the size of your data-set beforehand? You can design your more efficient data structures (you build your own hash-table, or build your own tree optimized by not having new call to every object stored, or even use some nice indexin
-
I'm kindof(CLazyObj) and I should use STL containers, but rely heavily on MFC containers. Are there any good books, docs or sites demonstrating STL containers? Norm
-
I'm kindof(CLazyObj) and I should use STL containers, but rely heavily on MFC containers. Are there any good books, docs or sites demonstrating STL containers? Norm
"The C++ Standard Library - A Tutorial and Reference" Nicolai M. Josuttis Addison Wesley ISBN 0201379260 $0.02 BR, Thomas
I am a signature virus! Help me spread and copy me to your sig!
-
(0) I use STL these days. Reasons, off-hand... (i) STL has great support for virtually all the important data structures and algorithms you are ever likely to run into (e.g. multimap, multiset, function objects), unlike MFC containers. (ii) Most MFC containers (perhaps all--haven't used them for a while now) carry the built-in CObject support for serialization, debug dumping. Thus they hookup into MFC's global static data, and can be a great help for detecting mem leaks, etc. (iii) MFC is better, I guess, for beginners due to its clear separation of argument type and access type. But typing-in two things again and again quickly becomes a boredom... (iv) Unless you typedef, typing boredom will catch you faster than you thought in STL too :) A few underlying diffs, thrown together randomly: (vi) MFC CMap uses hashtable, STL map and many others, including set, use a tree. Thus retrieval time of stored objects is data-*value* dependent in CMap. The retrieval is guarunteed to be in logarithmic time for STL map. (Not sure if STL's is a threaded tree--could someone please clarify?) Implication: If your data is peculiar (a very very unlikely scenario) CMap *can* be faster than STL map. Implication: STL map always delievers on the fastest possible search time for random data. (vii) MFC CMap computes hash after casting to DWORD any key value. This means it computes hash on the address of const char*, but not on the whole null terminated C string *contents*, as you might expect. (That's a potentially dangerous situation--and therefore CTypedPtrWhateverTheGoodName is better there--it reminds you of what you key type there really is). At least CMap used to do so in version that shipped with VC++ 4, and I haven't checked the internals of CMap since then. Pl. correct me if I am off-tracks here. STL map (and many many other STL containers) *copy* the object of the generic parameter T. Due to the underlying tree, if you are going to store structs by value, you must supply a copy ctor and a global < operator to let STL find the right place to put your data as the leaf. Copy overheads need to be considered. (viii) There may be certain (rare) times when you are better off not using either MFC or STL. Mostly performance related. As one example: Why bother with either if you know the size of your data-set beforehand? You can design your more efficient data structures (you build your own hash-table, or build your own tree optimized by not having new call to every object stored, or even use some nice indexin
I am not absolutelly sure, but: 1. std::map uses a binary tree. There are other map containers which can use hashes. 2. CMap has a special hash function for strings which hashes the actual chars, not the pointer.
-
"STL tutorial and reference guide", by Musser and Saini ISBN 0-201-63398-1 -- Alex Marbus www.marbus.net But then again, I could be wrong.
I would also recommend Generic Programming and the STL, by Matthew H. Austern. AW Professional Computing Series, ISBN 0-201-30956-4. Matthew Adams Development Manager Digital Healthcare Ltd
-
(0) I use STL these days. Reasons, off-hand... (i) STL has great support for virtually all the important data structures and algorithms you are ever likely to run into (e.g. multimap, multiset, function objects), unlike MFC containers. (ii) Most MFC containers (perhaps all--haven't used them for a while now) carry the built-in CObject support for serialization, debug dumping. Thus they hookup into MFC's global static data, and can be a great help for detecting mem leaks, etc. (iii) MFC is better, I guess, for beginners due to its clear separation of argument type and access type. But typing-in two things again and again quickly becomes a boredom... (iv) Unless you typedef, typing boredom will catch you faster than you thought in STL too :) A few underlying diffs, thrown together randomly: (vi) MFC CMap uses hashtable, STL map and many others, including set, use a tree. Thus retrieval time of stored objects is data-*value* dependent in CMap. The retrieval is guarunteed to be in logarithmic time for STL map. (Not sure if STL's is a threaded tree--could someone please clarify?) Implication: If your data is peculiar (a very very unlikely scenario) CMap *can* be faster than STL map. Implication: STL map always delievers on the fastest possible search time for random data. (vii) MFC CMap computes hash after casting to DWORD any key value. This means it computes hash on the address of const char*, but not on the whole null terminated C string *contents*, as you might expect. (That's a potentially dangerous situation--and therefore CTypedPtrWhateverTheGoodName is better there--it reminds you of what you key type there really is). At least CMap used to do so in version that shipped with VC++ 4, and I haven't checked the internals of CMap since then. Pl. correct me if I am off-tracks here. STL map (and many many other STL containers) *copy* the object of the generic parameter T. Due to the underlying tree, if you are going to store structs by value, you must supply a copy ctor and a global < operator to let STL find the right place to put your data as the leaf. Copy overheads need to be considered. (viii) There may be certain (rare) times when you are better off not using either MFC or STL. Mostly performance related. As one example: Why bother with either if you know the size of your data-set beforehand? You can design your more efficient data structures (you build your own hash-table, or build your own tree optimized by not having new call to every object stored, or even use some nice indexin
> STL map (and many many other STL containers) *copy* the object of the generic > parameter T. [...] Copy overheads need to be considered. That is why it is bad practice to place objects directly into STL containers. Although anyone that regularly does that, even with objects that reference-count their data, gets what they deserve! :) Peace! -=- James.
-
> STL map (and many many other STL containers) *copy* the object of the generic > parameter T. [...] Copy overheads need to be considered. That is why it is bad practice to place objects directly into STL containers. Although anyone that regularly does that, even with objects that reference-count their data, gets what they deserve! :) Peace! -=- James.
When you're working with large objects and STL it behooves you to use something like Coplien's reference-counting idiom (Advanced C++ Programming Styles and Idioms, Addison-Wesley, 1991) so you hide the bulky data behind a lightweight "handle" class. I implement this idiom in terms of the GoF Bridge pattern so that I can use handle objects polymorphically. I got a real taste of this several years ago when I was writing a real-time data acquisition system that used STL to manipulate things like list> where the vectors were about 200 kbytes. Adding OutputDebugString() calls to the constructors and destructors taught me a lot about thrashing memory in STL with temporary copies.
-
(0) I use STL these days. Reasons, off-hand... (i) STL has great support for virtually all the important data structures and algorithms you are ever likely to run into (e.g. multimap, multiset, function objects), unlike MFC containers. (ii) Most MFC containers (perhaps all--haven't used them for a while now) carry the built-in CObject support for serialization, debug dumping. Thus they hookup into MFC's global static data, and can be a great help for detecting mem leaks, etc. (iii) MFC is better, I guess, for beginners due to its clear separation of argument type and access type. But typing-in two things again and again quickly becomes a boredom... (iv) Unless you typedef, typing boredom will catch you faster than you thought in STL too :) A few underlying diffs, thrown together randomly: (vi) MFC CMap uses hashtable, STL map and many others, including set, use a tree. Thus retrieval time of stored objects is data-*value* dependent in CMap. The retrieval is guarunteed to be in logarithmic time for STL map. (Not sure if STL's is a threaded tree--could someone please clarify?) Implication: If your data is peculiar (a very very unlikely scenario) CMap *can* be faster than STL map. Implication: STL map always delievers on the fastest possible search time for random data. (vii) MFC CMap computes hash after casting to DWORD any key value. This means it computes hash on the address of const char*, but not on the whole null terminated C string *contents*, as you might expect. (That's a potentially dangerous situation--and therefore CTypedPtrWhateverTheGoodName is better there--it reminds you of what you key type there really is). At least CMap used to do so in version that shipped with VC++ 4, and I haven't checked the internals of CMap since then. Pl. correct me if I am off-tracks here. STL map (and many many other STL containers) *copy* the object of the generic parameter T. Due to the underlying tree, if you are going to store structs by value, you must supply a copy ctor and a global < operator to let STL find the right place to put your data as the leaf. Copy overheads need to be considered. (viii) There may be certain (rare) times when you are better off not using either MFC or STL. Mostly performance related. As one example: Why bother with either if you know the size of your data-set beforehand? You can design your more efficient data structures (you build your own hash-table, or build your own tree optimized by not having new call to every object stored, or even use some nice indexin
I like speed, personally, too. Check this out: http://codeguru.earthweb.com/mfc/comments/10999.shtml MFC's CList<> SLAUGHTERS std::list<> in the benchmarks... including STLPort's. Granted, they're simple benchmarks, but they're enough to make me question using anything STL without seriously benchmarking it first. A while ago, I used STL in my add-in. Because it was supposed to work on VC5 and VC6 using the same executable, I was unable to use STL due to the fact that msvcp60.dll had different exports than msvcp50.dll. Stupid, stupid, stupid. Shipping STLPort isn't a viable alternative, since it's DLL is >700k. Oh, and what's with the crappy naming convention for internal STL code anyway in implementations that aren't Rogue Wave? Joshua Jensen Author, Workspace Whiz! - A Visual Studio Add-in http://workspacewhiz.com/
-
I like speed, personally, too. Check this out: http://codeguru.earthweb.com/mfc/comments/10999.shtml MFC's CList<> SLAUGHTERS std::list<> in the benchmarks... including STLPort's. Granted, they're simple benchmarks, but they're enough to make me question using anything STL without seriously benchmarking it first. A while ago, I used STL in my add-in. Because it was supposed to work on VC5 and VC6 using the same executable, I was unable to use STL due to the fact that msvcp60.dll had different exports than msvcp50.dll. Stupid, stupid, stupid. Shipping STLPort isn't a viable alternative, since it's DLL is >700k. Oh, and what's with the crappy naming convention for internal STL code anyway in implementations that aren't Rogue Wave? Joshua Jensen Author, Workspace Whiz! - A Visual Studio Add-in http://workspacewhiz.com/
I take issue with that test. For starters, it's using a list for something it shouldn't. When using queues, you should use std::queue or std::deque (in this case std::deque because you're poping the front while pushing on the back). and for stack tests, you should use std::stack. CList might work better for all those non-list functions than std::list, but that's why the specializations exist. Use the proper tool for the job. I modifed your code to use std::stack and std::deque instead and here are my results: Release build on a Celeron 366 1 million stack insert/remove pairs CListEx = 130, CList = 120, std::stack = 221 1 million queue insert/remove pairs CListEx = 120, CList = 110, std::deque = 80 1 million iterations CListEx = 901, CList = 892, std::list = 1211 Notice that std::deque is quite a bit faster than CList. std::stack is still slower, but nowhere near the 1172 that std::list provided. Strangely, my list iterations show a wider range than your tests did. This is on the stl that comes with VC6. The STL that will ship in VC7 is much faster, and will likely beat MFC in every instance.