It seems that the interface method wins for O1 and the function pointer method wins all other times. The expected use-case of the library will be high-level class-based programs. There will be lots of related callbacks.
With std::function, there's full freedom. With function pointers, you'd have to use static functions and somehow give access to user-related data. With the interface, it would match the use-case the best.
I'm wondering what your opinions and suggestions are for which method to go with? I'm going for high-level but optimized for speed.
cmiiw: `steady_clock' does not measure `user' time.
With -O3 I'm having %15 overhead for functor, and %130 for the interface (against function pointer)
¿what kind of advantages do you see in `Interface' ?
as for optimizing for speed, both function pointers and std::function require hard-to-optimize indirection. If you can decide which callback gets called at compile time, then template on the callback type so that it can be inlined:
1 2 3 4 5 6
auto new_meh = make_new_meh(yzz);
{
std::chrono::steady_clock::time_point start {std::chrono::steady_clock::now()};
for(std::size_t i {0}; i < 10000000; ++i)
{
new_meh.DoStuffFast();
22267
20936
31309
7093
(I had to make x a volatile int, or it was optimized out completely)
None of the callbacks can be inlined, unfortunately, or I would use std::function. I had meant to use O3, the link was just to an O0 test I did out of curiosity.
@Disch: So, I would take away the use case to see which is better? That doesn't make sense.
@ne555: I'm not trying to measure the user time. The interface method would allow for the high-level ease-of-use that I am going for with the library (the user would already have their class and they could just implement the interface).
@Disch: So, I would take away the use case to see which is better? That doesn't make sense.
The goal is to test which callback mechanism is faster, right? You're not trying to test the bodies of the callbacks.
For you to do this properly, the bodies of each test callback must do the same thing. Right now they are doing different things, and as a result you are giving one mechanism an unfair advantage.
I'm not testing which callback method is faster, I already know that. I'm showing an example with the various callback methods and use cases and asking which one you think would be better.
@ne555: The output is for measuring the time for the whole callback to occur, including use-case overhead, which gives me more accurate results for what I am testing.
ne555 wrote:
> The interface method would allow for the high-level ease-of-use
¿how is that different from the functor approach?
By "functor approach" I guess you mean "std::function approach". I could bind differently-named functions into a std::function, I guess, but I want the most automagic experience so less time is spent writing the connection and registration code and more time is spent implementing the callbacks and the rest of the application.