# How to inline this function call so it behaves the same

**URL:** <https://discuss.ocaml.org/t/how-to-inline-this-function-call-so-it-behaves-the-same/15479>\
**Category:** Learning\
**Tags:** flambda, inlining, performance\
**Created:** [October 21, 2024, 8:17am UTC](https://discuss.ocaml.org/t/how-to-inline-this-function-call-so-it-behaves-the-same/15479 "2024-10-21T08:17:22Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![patrick-nicodemus](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/patrick-nicodemus/32/4704_2.png) [@patrick-nicodemus](https://discuss.ocaml.org/u/patrick-nicodemus)\
**Post date:** [October 21, 2024, 8:17am UTC](https://discuss.ocaml.org/t/how-to-inline-this-function-call-so-it-behaves-the-same/15479/1 "2024-10-21T08:17:22Z")

</div>

I am not familiar with the use of flambda, so perhaps I have just overlooked this in the documentation. This code is from Oleg Kiselyov’s essay on modularity, “Lightweight static guarantees” (well, a minimized version of the code to highlight the performance issue.) In his paper he is trying to make the point that we can get good performance without sacrificing correctness guarantees, so it would be really nice if I could figure out how to make reality live up to the ideal and make the code actually run fast.

There is a factor of 5 performance difference between these two loops and I am wondering what is going on or how to properly inline the function or configure flambda. I have used `-O3` and `-rounds 5` separately but I’m just not sure what’s going on. Is there a semantic reason it can’t be inlined and it has to allocate it? Any advice is appreciated.

```auto
let [@inline] bcmp i j = if i <= j then Some (i, j) else None

let test () =
  let ctr = ref 0 in
  let t0 = Unix.gettimeofday () in
  for i = 0 to 1_000_000 do
    let x = match bcmp i (i/2 +1) with Some (i,j) -> i + j | None -> 0 in
    ctr := !ctr + x
  done;
  let t1 = Unix.gettimeofday () in
  Printf.printf "With function call: %f\n" (t1 -. t0);

  let ctr = ref 0 in
  let t0 = Unix.gettimeofday () in
  for i = 0 to 1_000_000 do
    let j = (i/2 + 1) in
    let x = match if i <=j then Some (i, j) else None with Some (i,j) -> i + j | None -> 0 in
    ctr := !ctr + x
  done;
  let t1 = Unix.gettimeofday () in
  Printf.printf "No function call: %f\n" (t1 -. t0);

```

I also tried defining bcmp locally in the loop body and it didn’t help.

---

<div class="post-metadata">

**Author:** ![silene](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/silene/32/2707_2.png) [@silene](https://discuss.ocaml.org/u/silene)\
**Post date:** [October 21, 2024, 8:55am UTC](https://discuss.ocaml.org/t/how-to-inline-this-function-call-so-it-behaves-the-same/15479/2 "2024-10-21T08:55:51Z")

</div>

The issue is not that `bcmp` is not inlined. The issue is that the inlined code is not being specialized for integer arguments. Instead, it uses the polymorphic comparison, which is costly. If you change the code to

```ocaml
let [@inline] bcmp (i:int) j = if i <= j then Some (i, j) else None

```

it should work a lot better.
