IIUC the "object dispatch integer"/"object dispatch string" benchmarks
are the things you were referring to. Those simulate what the engine
would see with virtual dispatch and completely different type maps,
just without the source overhead of creating an entire class just for
a little benchmark.
And also, engines *won't* be able to optimize them generally, because
there could be infinitely many type maps, and after about 200 or so
types, the `switch` statement ends up *much* slower.
-
Isiah Meadows
cont...@isiahmeadows.com
www.isiahmeadows.com
On Sat, Mar 2, 2019 at 3:43 AM Naveen Chawla wrote:
>
> I don't think those benchmarks test exactly what we are talking about. They
> have a dictionary/array look up followed by method dispatch, vs switch case
> and execute. Removing the look up it would be: `x.doStuff()` vs
> `switch(x.type)...`. Make sense? Don't have time to do it right now.
>
> Logically I think the JS engine can make them perform identically, so even if
> benchmarks show something today, I would not be concerned for the future and
> so would prefer to opt for the paradigm that offers the best manageability,
> which I think is inheritance by a significant margin, in the cases mentioned.
> Other types of cases could of course be a whole different story.
>
> On Sat, 2 Mar 2019, 5:24 am Isiah Meadows, wrote:
>>
>> > It would be unthinkable for it to use pattern matching or explicit code
>> > branchinI'm g instead of method inheritance for type disambiguation during
>> > render
>>
>> But it frequently does internally. For example:
>>
>> - Calculating object projections:
>> https://github.com/mrdoob/three.js/blob/dev/src/renderers/WebGLRenderer.js#L1243-L1351
>> - Rendering object *lists*:
>> https://github.com/mrdoob/three.js/blob/dev/src/renderers/WebGLRenderer.js#L1353-L1411
>> - Setting the rendering mode and controlling basic rendering:
>> https://github.com/mrdoob/three.js/blob/dev/src/renderers/WebGLRenderer.js#L802-L874
>>
>> Obviously, it exposes a data-oriented, object oriented API. And it
>> does appear it's not *exclusively* conditionals:
>>
>> - It invokes an dynamic `render` method for "immediate render
>> objects":
>> https://github.com/mrdoob/three.js/blob/dev/src/renderers/WebGLRenderer.js#L636-L644
>> - In `renderBufferDirect`, it does virtual method dispatch on `render`
>> based on one of two possible types, but it otherwise uses conditionals
>> for everything:\*
>> https://github.com/mrdoob/three.js/blob/dev/src/renderers/WebGLRenderer.js#L707-L876
>> - It uses a fair bit of functional programming in `compile`:
>> https://github.com/mrdoob/three.js/blob/dev/src/renderers/WebGLRenderer.js#L1009-L1054
>>
>> However, I'm finding exceptions in its core and renderers, and it
>> doesn't appear virtual dispatch is *that* broadly and pervasively
>> used, even though it uses methods a lot.
>>
>> \* This seems like overkill when the diff between the two renderers in
>> question [1] [2] consist of an extra method + 2 extra variables [3]
>> [4], a few changed method invocations [5] [6], and the rest just due
>> to a different name and a useless `var`.
>>
>> [1]:
>> https://github.com/mrdoob/three.js/blob/dev/src/renderers/webgl/WebGLBufferRenderer.js
>> [2]:
>> https://github.com/mrdoob/three.js/blob/dev/src/renderers/webgl/WebGLIndexedBufferRenderer.js
>> [3]:
>> https://github.com/mrdoob/three.js/blob/dev/src/renderers/webgl/WebGLIndexedBufferRenderer.js#L15-L22
>> [4]:
>> https://github.com/mrdoob/three.js/blob/dev/src/renderers/webgl/WebGLIndexedBufferRenderer.js#L61
>> [5]:
>> https://github.com/mrdoob/three.js/blob/dev/src/renderers/webgl/WebGLIndexedBufferRenderer.js#L26
>> [6]:
>> https://github.com/mrdoob/three.js/blob/dev/src/renderers/webgl/WebGLIndexedBufferRenderer.js#L53
>>
>> > I'm curious where you got the idea that method invocation is "far" slower
>> > than explicit code branching?
>>
>> - In C++: https://stackoverflow.com/a/8866789
>> - JS benchmark with 4 variants (typed method dispatch is polymorphic):
>> http://jsben.ch/fbJQH
>> - JS benchmark with 12 variants (typed method dispatch is
>> megamorphic): http://jsben.ch/aWNDN
>>
>> And in my experience, the speed difference in real-world
>> performance-critical code is not unlike that microbenchmark and is
>> sometimes even more drastic, especially if it's a linked list instead
>> of just a simple array lookup.
>>
>> I'd like to emphasize I'm specifically referring to the case where the
>> engine can't reliably assume a single method receiver, i.e. when it
>> *has* to fall back to dynamic dispatch.
>>
>> -
>>
>> Isiah Meadows
>> cont...@isiahmeadows.com
>> www.isiahmeadows.com
>>
>> On Fri, Mar 1, 2019 at 6:25 AM Naveen Chawla wrote:
>> >
>> > The entire renderers, cameras, meshes etc. hierarchy uses method
>> > inheritance and many of those methods are called during scene rendering
>> > (which is performance sensitive as it happens per frame). It would be
>> > unthinkable for it to use