WebGLLights: Inefficient string concatenations
See original GitHub issueRelated PR: https://github.com/mrdoob/three.js/pull/14568
This line is executed 60 times per second thus produces garbage as seen on Chrome’s Allocation Profiler:
The hash value of WebGLLights should be an object instead of concatanated string:
hash: {
stateID: -1,
directionalLength: -1,
pointLength: -1,
spotLength: -1,
rectAreaLength: -1,
hemiLength: -1,
shadowsLength: -1
}
In the WebGLRenderer.js the values should be compared as:
} else if ( materialProperties.lightsHash.stateID !== lights.state.hash.stateID ||
materialProperties.lightsHash.directionalLength !== lights.state.hash.directionalLength ||
materialProperties.lightsHash.pointLength !== lights.state.hash.pointLength ||
materialProperties.lightsHash.spotLength !== lights.state.hash.spotLength ||
materialProperties.lightsHash.rectAreaLength !== lights.state.hash.rectAreaLength ||
materialProperties.lightsHash.hemiLength !== lights.state.hash.hemiLength ||
materialProperties.lightsHash.shadowsLength !== lights.state.hash.shadowsLength ) {
Since JS assigns objects by reference materialProperties.lightsHash should be updated like this to avoid potenial bugs caused by string to object switch:
materialProperties.lightsHash.stateID = lights.state.hash.stateID;
materialProperties.lightsHash.directionalLength = lights.state.hash.directionalLength;
materialProperties.lightsHash.pointLength = lights.state.hash.pointLength;
materialProperties.lightsHash.spotLength = lights.state.hash.spotLength;
materialProperties.lightsHash.rectAreaLength = lights.state.hash.rectAreaLength;
materialProperties.lightsHash.hemiLength = lights.state.hash.hemiLength;
materialProperties.lightsHash.shadowsLength = lights.state.hash.shadowsLength;
instead of:
materialProperties.lightsHash = lights.state.hash
Any ideas/opinions?
Issue Analytics
- State:
- Created 5 years ago
- Comments:12 (10 by maintainers)
Top Results From Across the Web
WebGLLights state and its hashing produce unintended ...
WebGLLights.hash property is used to determine whether or not a material needs to ... WebGLLights: Inefficient string concatenations #14576.
Read more >Inefficient use of string concatenation - Stack Overflow
I was creating a logger in my java-app (with NetBeans as IDE) when suddenly I saw a warning saying: "Inefficient use of string...
Read more >Inefficient string concatenation inside loop Medium
Concatenating immutable sequences results in a new object. This causes a quadratic runtime cost when done inside loop. Detector ID.
Read more >Is it inefficient to concatenate strings one at a time?
In some browsers, string concatenation appears to be optimized automatically, and in other cases it isn't. So the recommendation (at least ...
Read more >How To Efficiently Concatenate Strings In Python
To be precise, inefficient. Today, we shall discuss string concatenation in python and how to do it efficiently.
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
@Usnul
You’re absolutely right abot the hash concept here but this issue is about reducing the GC activity by avoiding creation of new objects in the render loop. In the solution proposed by me the objects are created only once but their properties (which are all integer values, no strings here) are changed inside the loop so it should be quite cheap considering the memory usage. If I understood your proposal correctly a new String object would be created inside the render loop anyway when we hash couple of integers together (AFAIK you cannot reuse Strings since they are immutable objects). So your proposal is exactly what I suggest avoiding in this issue.
I’m not saying it’s not a good idea or anything, it is just against what this issue proposes that’s all 😃
Well, to avoid guesses as to my position. I believe a 32bit integer is sufficient in a lot of cases, and beyond that I would guess a decent 128 bit non-cryptographic hashing like metro-hash is a good solution.
A note about 32bits - integers in JS are 32 bit explicitly, whenever you decide to use any bit twiddling operations - a number gets truncated to a 32bit int.