Slower than what? More space than what? Are we comparing using objects to calling functions in a module known at compile-time, to using a record with one field for each method, or to using a GADT, for example?
The link says:
The first field of the block refers to the object’s class and associated method suite, in a format that cannot easily be exploited from C. The second field contains a unique object ID, used for comparisons. The remaining fields of the object contain the values of the instance variables of the object.
This is exactly what you would expect (except possibly the ID). The benchmark I gave earlier compared against a GADT:
type source = Source : (module SOURCE with type t = 'a) * 'a -> source
So here, the first field is the method table (module) and the second is a pointer to the record with the instance variables. We’ve lost the ID field, but gained an extra block and an extra indirection.
But method lookup is slower (a pre-computed hash rather than a record index).
There are some other benchmarks at GitHub - talex5/flow-tests: Just for testing, and there are also some notes at eio/doc/rationale.md at main · ocaml-multicore/eio · GitHub.
My thoughts are:
- Avoiding objects is a benefit for speed-critical code, especially if you know the target statically.
- If you need sub-types, objects will be a good choice.
- For most uses, the overhead won’t matter compared to whatever other processing you’re doing.