ocaml-containers icon indicating copy to clipboard operation
ocaml-containers copied to clipboard

perf: use a monomorphic impl for CCMonomorphic.{min,max}

Open c-cube opened this issue 1 year ago • 6 comments

close #452

c-cube avatar Jun 03 '24 14:06 c-cube

From my testing, it seems enough to define min as:

let min (x:int) (y:int) = if x <= y then x else y

But my testing was with flambda enabled. Something that might be enough also is to do:

let min (x:int) (y:int) = Stdlib.min x y

But I did not try it to see if this is enough. With both solution we would not need the conditional compilation.

FardaleM avatar Jun 03 '24 14:06 FardaleM

let min (x:int) (y:int) = Stdlib.min x y

I've never seen before this be faster than let min = Stdlib.min? :/ if it is, we have a problem cause this is also how compare, etc are done. But anyway, I'd rather delegate to Int.min since it might become an intrinsic in the future.

c-cube avatar Jun 03 '24 14:06 c-cube

I would need to look how it is compiled. The question is, does the compiler specialised the compare function or not. If not, then it goes through the polymorphic compare which is slow. That's how I found it, the min function was calling the runtime C function on my case. We would need to check if this is the case also for the other functions. But I don't know how to check that.

FardaleM avatar Jun 04 '24 11:06 FardaleM

Easiest is godbolt (https://ocaml.godbolt.org/), e.g.

https://ocaml.godbolt.org/#g:!((g:!((g:!((h:codeEditor,i:(filename:'1',fontScale:14,fontUsePx:'0',j:1,lang:ocaml,selection:(endColumn:58,endLineNumber:4,positionColumn:58,positionLineNumber:4,selectionStartColumn:58,selectionStartLineNumber:4,startColumn:58,startLineNumber:4),source:'%0Alet+cint+:+int+-%3E+int+-%3E+int+%3D+Stdlib.compare%0Alet+()+%3D%0A++Printf.printf+%22%25d%5Cn%22+(Sys.opaque_identity+(cint+42+41))'),l:'5',n:'1',o:'OCaml+source+%231',t:'0')),k:50,l:'4',n:'0',o:'',s:0,t:'0'),(g:!((h:compiler,i:(compiler:ocaml5000flambda,filters:(b:'0',binary:'1',binaryObject:'1',commentOnly:'0',debugCalls:'1',demangle:'0',directives:'0',execute:'1',intel:'0',libraryCode:'0',trim:'1',verboseDemangling:'0'),flagsViewOpen:'1',fontScale:14,fontUsePx:'0',j:1,lang:ocaml,libs:!(),options:'',overrides:!(),selection:(endColumn:1,endLineNumber:1,positionColumn:1,positionLineNumber:1,selectionStartColumn:1,selectionStartLineNumber:1,startColumn:1,startLineNumber:1),source:1),l:'5',n:'0',o:'+x86-64+ocamlopt+5.0.0-flambda+(Editor+%231)',t:'0')),k:50,l:'4',n:'0',o:'',s:0,t:'0')),l:'2',n:'0',o:'',t:'0')),version:4

-- Simon Cruanes

c-cube avatar Jun 04 '24 14:06 c-cube

I tried to play to see the case for min, but I don't see the function, so I don't know how to interpret this.

FardaleM avatar Jun 04 '24 19:06 FardaleM

it might be because polymorphic min isn't in the compiled code, it's part of the runtime.

c-cube avatar Jun 05 '24 01:06 c-cube