Closed silverlyra closed 1 year ago
Thanks for the detailed report, it's super helpful 👍 As I said earlier, it probably makes sense to use core
because it will always be faster if you build something for a specific use-case. However, most of these performance issues have a solution, so maybe I should dedicate some time to fixing them 🙂
Basically, except for the garbage collection, these are issues that I have seen before when profiling. I recently did one optimisation pass, so it is already better, but I think it's time to rethink the idea of using the shader source as the key into a cache of shader programs. That solution was not necessarily meant to be permanent, it was just easy to test out the design this way. And well, if the default hashing and string building was not so slow, it would probably have been good enough - but it is slow and I usually say that to everyone who wants to listen 😆 Anyway, I'll change the key to be some integers that are fast to generate instead and that should solve the string building, the garbage collection of strings and the string hashing - so basically all problems at once 💥 The problem will then be to create unique ids for geometries, materials and lights, which wouldn't be a problem if they could not be created outside of three-d
, but they can 😬 But well, I think it's worth it, the performance gain outweighs the downside that it will be a bit more difficult and error prone to do custom geometries, materials and lights.
I couldn’t figure out how to get non-opaque colors to work without adding a light, and I noticed that framerates got worse when I did.
That's interesting. You have vertex colors? You might need to use the ColorMaterial::new_transparent
instead of ColorMaterial::new
? And yes, that will definitely make a negative impact on performance before the above problems are solved.
FYI, working on this in the optimisation
branch.
On #350 I mentioned wanting to switch to using
core
exclusively due to performance problems I ran into using the tools in therenderer
module, but I didn’t elaborate 😆 on what I was seeing.Here’s a capture from Chrome’s profiler of one of our
requestAnimationFrame
callbacks. This is a wasm-packprofiling
build (optimizations + debuginfo):I couldn’t figure out how to get non-opaque colors to work without adding a light, and I noticed that framerates got worse when I did. The profile confirms the light did that; 40% of each frame is spent in
lights_shader_source
, building aString
on every frame. (There’s only one fixedAmbientLight
in my scene.)Another ~50% of each frame is spent in
HashMap::get
. It’s not obvious where this is coming from with optimizations enabled, but if I re-run my app in adebug
build:It seems this is happening in
Context::program
, with most of theHashMap
time spent computing the hashes themselves.The bottom-up profiler view shows that it’s
lights_shader_source
which is responsible for most of the garbage collection which runs during frames:I wonder if building that shader source in a reusable buffer (instead of allocating a new
String
every time) would make that part of the problem go away.