
2016-04-14 17:47 GMT+02:00 Peter Dimov <lists@pdimov.com>:
Chris Glover wrote:
That's hard to believe. Copying a pointer should be insignificant > compared to the cost of the dispatch. What does the profiler say?
Which compiler? I have found that MSVC is extremely pessimistic with this type of situation and generates unnecessary mov instructions for the pointer in the struct.
It's inside a switch on the type index. A mov instruction or two shouldn't matter. The generated code should be something like
switch( v.which() ) { case 0:
my_visitor( get<T1>(v) ); break;
case 1:
my_visitor( get<T2>(v) ); break;
// and so on }
except with about seven layers of templates on top. I just don't see an extra pointer copy being of significance here. If the switch is compiled to a table you have an indirect jmp; if to a sequence of comparisons, would depend on how well they can be predicted.
Thank you for putting it this way. Ultimately my goal is to compare two ways of representing a (mathematical) expression tree. I tried one with OO-based virtual dispatch: ``` struct AdditioNode : NodeInterface { unique_ptr<NodeInterface> leftSubexpression, rightSubexpression; double eval() override; }; // etc... ``` And storing variants in a vector and representing links to subnodes as indexes: ``` struct Addition { int leftSubexpression, rightSubexpression; }; using Node = variant<Addition, ...>; using ExpressionTree = vector<Node>; ``` I haven't done any profiling yet, but my benchmarks show, the former one (with virtual interfaces) is about twice faster. I found it quite surprising. Regards, &rzej