"Super" hoisting

Brian Barnes ggadwa at charter.net
Thu May 12 18:53:13 UTC 2016


Not by my testing, at least.

My original example is a simple one to explain what the procedure is.  Here’s a more complex example, from my code, from my mesh classes.  This function updates the vertices in the mesh based on the position of the bones of a skeleton, it gets called every frame for every model mesh that can be seen in the scene:

    updateVertexesToPoseAndPosition(view,skeleton,angle,position)
    {
        var n,v;
        var bone,parentBone;
        
            // move all the vertexes
            
        var vIdx=0;
        var nIdx=0;
        
        for (n=0;n!==this.vertexCount;n++) {
            v=this.vertexList[n];
            
                // bone movement
                
            bone=skeleton.bones[v.boneIdx];
                
            this.rotVector.setFromPoint(v.vectorFromBone);
            this.rotVector.rotate(bone.curPoseAngle);
            
            this.rotVector.x=bone.curPosePosition.x+this.rotVector.x;
            this.rotVector.y=bone.curPosePosition.y+this.rotVector.y;
            this.rotVector.z=bone.curPosePosition.z+this.rotVector.z;
            
            this.rotNormal.setFromPoint(v.normal);
            this.rotNormal.rotate(bone.curPoseAngle);
            
                // average in any parent movement
                
            if (v.parentBoneIdx!==-1) {
                parentBone=skeleton.bones[v.parentBoneIdx];
                
                this.parentRotVector.setFromPoint(v.vectorFromParentBone);
                this.parentRotVector.rotate(parentBone.curPoseAngle);

                this.parentRotVector.x=parentBone.curPosePosition.x+this.parentRotVector.x;
                this.parentRotVector.y=parentBone.curPosePosition.y+this.parentRotVector.y;
                this.parentRotVector.z=parentBone.curPosePosition.z+this.parentRotVector.z;

                this.parentRotNormal.setFromPoint(v.normal);
                this.parentRotNormal.rotate(parentBone.curPoseAngle);
                
                this.rotVector.average(this.parentRotVector);
                this.rotNormal.average(this.parentRotNormal);
            }    
            
                // whole model movement
                
            this.rotVector.rotate(angle);
            
            this.drawVertices[vIdx++]=this.rotVector.x+position.x;
            this.drawVertices[vIdx++]=this.rotVector.y+position.y;
            this.drawVertices[vIdx++]=this.rotVector.z+position.z;
            
            this.rotNormal.rotate(angle);
            
            this.drawNormals[nIdx++]=this.rotNormal.x;
            this.drawNormals[nIdx++]=this.rotNormal.y;
            this.drawNormals[nIdx++]=this.rotNormal.z;
        }
        
            // set the buffers
            
        var gl=view.gl;
        gl.bindBuffer(gl.ARRAY_BUFFER,this.vertexPosBuffer);
        gl.bufferData(gl.ARRAY_BUFFER,this.drawVertices,gl.DYNAMIC_DRAW);
        
        gl.bindBuffer(gl.ARRAY_BUFFER,this.vertexNormalBuffer);
        gl.bufferData(gl.ARRAY_BUFFER,this.drawNormals,gl.STATIC_DRAW);
    }

Notice that rotVector, rotNormal, parentRotVector, and parentRotNormal, are all “this”, i.e., globals.  They are *only* used in this function, no where else in the class.  If I put them as local variables, I get enormous GC pauses.  If I don’t, I get none (granted, I have to do this everywhere, so it’s just not this function.)

The example I gave existed only to show how it would work; not a real example.  Here’s a real example, that shows obvious problems with local variables.  Yes, these are objects.

Not that moving the objects would ONLY be something that happened at compile time and would be a hint; they wouldn’t be effected in the warm up runs.  You’d almost have to say that same hint would force a compile (which has it’s own problems.)

[>] Brian

> On May 12, 2016, at 1:33 PM, Allen Wirfs-Brock <allen at wirfs-brock.com> wrote:
> 
> 
>> On May 12, 2016, at 9:39 AM, Brian Barnes <ggadwa at charter.net> wrote:
>> 
>> ...
>> If I call doSomething a lot of times, I get a lot of objects to be tracked and GC’d.  Yes, I can rewrite that code to obviously eliminate them, but pretend there is actually something interesting happening here that requires those variables.  And engines can be smart enough to mark them and deal with them with the function ends (I don’t know if this is done.)
>> 
>> What I’m thinking is some kind of class based hint that would “super” hoist all local function variables.  It would be sugar but it would transform it into:
>> 
> 
> 
> 
> Local variables like a,b,c in your example are probably the least expensive construct in JS. In your example, there are no objects created by doSomething, not state that persists after doSomething  returns, and no GC pressure. Anything you do WRT moving such local state into object properties is going to be more expensive.
> 
> Allen
> 



More information about the es-discuss mailing list