0

I am adding metrics calls to my Go program using Prometheus. I decided to separate all the Prometheus calls to simple function calls in a separate source file for maintainability (in case I want to move to a different metrics package). But more important it also makes it faster to write the code as the IDE will prompt with the label names as parameters to the function call. Eg something like this:

var requestCounter = promauto.NewCounterVec(prometheus.CounterOpts{}, []string{"name"})

func incrementRequestCounter(label1, label2 string) {
    requestCounter.WithLabelValues(label1, label2).Inc()
}

Some of these functions are called often in a low-level loop so I don't want these calls to slow down the code too much. My assumption was that such a simple line of code would be easy to inline. However checking (with build option --gcflags -m) I found that the above single line function is not inlined (go1.12.5 windows/amd64). Does anyone know why? And how to get around this? Note that this function is inlined:

func incrementRequestCounter(label1, label2 string) {
    requestCounter.WithLabelValues(label1, label2)
}

With further experimentation it seems that a function will not be inlined if it has more than one call to non-inlineable functions. (You can have lots of calls to inlineable functions and a function will still be inlineable.)

AJR
  • 1,547
  • 5
  • 16
  • 2
    See [Stimulate code-inlining](https://stackoverflow.com/questions/41119734/stimulate-code-inlining/41119979#41119979). – icza Oct 31 '19 at 10:30
  • 1
    There's no indication in your question if you're actually measuring a performance problem that you've narrowed down to the function call overhead here. This seems like premature optimization. – Adrian Oct 31 '19 at 13:24
  • The ability to inline code is always changing, so this is probably a better question for the Go developers than here. Mid-stack inlining itself is rather new, and while your function may look "simple", the actual complexity still depends on the analysis of all the functions it calls. – JimB Oct 31 '19 at 16:01
  • @Adrian I benchmarked the code and you are correct that the function call overhead is negligible. I have learnt to benchmark first! But I also found that the Prometheus calls are a little slower than I thought - luckily I found it quite easy move them outside tight inner loops (using Add() instead of Inc()). – AJR Nov 05 '19 at 05:54

1 Answers1

0

Just posting an answer (since nobody else has) with these points:

  1. Benchmark before trying to optimise.
  2. A seemingly simple function may be difficult to inline
  3. Inlining is evolving and the above may be inlined in the future
AJR
  • 1,547
  • 5
  • 16