I saw that there was some argument over how much slower slot access is than struct access, so
I just decided to measure it naively. I made a two slot sruct and a CLOS version of a CONS cell
with car and cdr slots
and I ran LTAK using regular lists, `lists' made from CLOS conses, and `lists' made from structs.
Here are the results:
D:\repositories\clos-benchmark>sbcl --script run-benchmarks.lisp Benchmark: ltak over native cons cells, CLOS my-cons nodes, and my-cons-struct nodes Inputs: x=15 y=9 z=4 repeats=35 Scenario min-ms mean-ms max-ms ratio -------------------------------------------------------------------- native standard 0.129 0.146 0.186 clos standard 1.346 1.365 1.475 9.37x struct standard 0.172 0.175 0.179 1.20x native optimized 0.068 0.069 0.073 clos optimized 0.411 0.414 0.419 6.04x struct optimized 0.068 0.069 0.073 1.01x
In this naive use case, structs are same as native cons cells, but CLOS objects are one ninth the speed of a struct or cons cell if you just use it unoptimized, and one sixth the speed if optimizations are turned on.
But the CLOS instance is more functional than the cons cell in mimics. For instance, I could add a slot to the class and all the instances would be lazily updated with the new slot. I can also subclass the CLOS class and the selector functions will continue to work. Finally, I can redefine the CLOS closs while I'm developing it and all the instances will be uppdated. THe machinery to keep all this running is costing us our factor of 9.
But this might be worth the cost if we are running on a network where the bulk of the time will be transmitting the answer down the pipe once it is computed. Taking a few extra milliseconds to compute the answer might be worth the convenience features of CLOS.
2 comments:
What does it mean CLOS access? sbcl documentation discusses several options of slot access (https://www.sbcl.org/manual/#Slot-access) with varying speeds. If you want to re-check their figures, would it make sense to try all the cases, or at least document which one was tested?
This is naive just using the accessor defined on the slot. So you get the generic function dispatch on the accessor in addition to the call through slot-value.
I wasn't trying to rigorously check their figures but rather get a rough idea of the gross cost of using CLOS vs. using a struct when you don't try to optimize.
Post a Comment