6

problem is simple: We have a class that has members a,b,c,d... We want to be able to quickly search(key being value of one member) and update class list with new value by providing current value for a or b or c ... I thought about having a bunch of
std::map<decltype(MyClass.a/*b,c,d*/),shared_ptr<MyClass>>.

1) Is that a good idea?

2) Is boost multi index superior to this handcrafted solution in every way?

PS SQL is out of the question for simplicity/perf reasons.

NoSenseEtAl
  • 28,205
  • 28
  • 128
  • 277
  • "*Is boost multi index superior to this handcrafted solution in every way?*" MultiIndex does not yet support move semantics. :-[ – ildjarn Sep 26 '12 at 19:22

2 Answers2

7
  1. Boost MultiIndex may have a distinct disadvantage that it will attempt to keep all indices up to date after each mutation of the collection. This may be a large performance penalty if you have a data load phase with many separate writes.

  2. The usage patterns of Boost Multi Index may not fit with the coding style (and taste...) of the project (members). This should be a minor disadvantage, but I thought I'd mention it

  3. As ildjarn mentioned, Boost MI doesn't support move semantics as of yet

Otherwise, I'd consider Boost MultiIndex superior in most occasions, since you'd be unlikely to reach the amount of testing it received.

sehe
  • 374,641
  • 47
  • 450
  • 633
  • regarding the amount of testing.... it is a hard comparison since handcrafted solution has a lot less testing but also a lot less LOC – NoSenseEtAl Sep 27 '12 at 11:06
  • Good thing it is only my opinion, then :) - At least the Boost LOC have been peer reviewed by more pairs of eyes than most in-house teams can afford. – sehe Sep 27 '12 at 11:51
1

You want want to consider containing all of your maps in a single class, arbitrarily deciding on one of the containers as the one that stores the "real" objects, and then just use a std::map with a mapped type of raw pointers to elements of the first std::map.

This would be a little more difficult if you ever need to make copies of those maps, however.

David Stone
  • 26,872
  • 14
  • 68
  • 84
  • Or just iterators into the first map instead of raw pointers to its elements. – Christian Rau Sep 27 '12 at 09:49
  • am I wrong to think that sizeof shared_ptr compared to sizeof iterator isnt that big of a problem, esp since iirc map has 3 pointers per element – NoSenseEtAl Sep 27 '12 at 10:10
  • @ChristianRau Iterators into the first map I think would be the wrong way to go for most applications. They would require you to do something like `map.find(key)->second->second` rather than just `map.find(key)->second`. You're adding an extra layer of indirection for no benefit. – David Stone Sep 28 '12 at 00:46
  • @NoSenseEtAl The issue isn't with size. The size of an iterator should be equal to a raw pointer, and the size of a `shared_ptr` isn't that much bigger, so for most applications, it's not such a big deal (unless you're mapping a lot of small objects). However, there is a performance penalty for using reference counting, and you don't need it. Using a map with raw pointers to the element for all but one map will give you identical use with superior performance. In other words, try not to pay for functionality you don't need. – David Stone Sep 28 '12 at 00:48
  • boost shared_ptr (with disabled thread safe refcounting) it is. :) but seriously atomic ref counting is expensive compared to normal refcounting but I think that most of the cost in RB tree based containers is jumping through memory... if(and its a big if) I get some time over weekend I might try to see the diff between your optimized and naive solution. – NoSenseEtAl Sep 28 '12 at 08:16