question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

`Object.defineProperty` in `THREE.Vector3` constructor causing a significant performance penalty

See original GitHub issue

Describe the bug

I’ve noticed a significant performance drop in my application when I upgraded the THREE.JS version. Initially from 0.102.0 to 0.125.2, but I’ve narrowed it down to a change from 0.119.1 to 0.120.0. A single model step in my app (simulation) increased from ~10ms to ~50ms.

I’ve used JS profiler and noticed that Vector3.clone() is at the top now: Screenshot 2021-02-15 at 18 34 12

I’m using THREE.Vector3 in the simulation part of the app, and since many vector operations are implemented in place, .clone() calls are very common. When I downgrade version to 0.119.1, the clone operation isn’t there anymore and the model step calculates 4 times faster.

I did a little investigation and replacing Object.defineProperty( this, 'isVector3', { value: true } ); in THREE.Vector3 constructor with this.isVector3 = true; fixes the issue.

To Reproduce, Live example

On my machine, the difference is 5ms (r119) vs 45ms (r120, r125).

I don’t think it’d be useful here, but the app I’m working on: https://tectonic-explorer.concord.org/?preset=subduction

Expected behavior

No .clone performance drop.

Screenshots

THREE.JS version 0.119.1 vs 0.120.0:

Screenshot 2021-02-15 at 18 33 25

Platform:

  • Device: Desktop
  • OS: MacOS
  • Browser: Chrome v88
  • Three.js version: r120.0 and newer, r119 is the last one that works fine

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:3
  • Comments:11 (6 by maintainers)

github_iconTop GitHub Comments

1reaction
WestLangleycommented, Feb 16, 2021

My .clone() calls are spread all over the codebase… It’s thousands of lines, different classes, methods, and getters.

@pjanik Right. That is what I assumed.

If you are calling clone() often enough per animation frame to incur a measurable performance hit, then you are misusing the method.

The three.js math classes do not use the method at all.

Just a friendly tip. 😃

1reaction
pjanikcommented, Feb 15, 2021

FYI, my jstfiddle example is just the simplest test case I could imagine. It doesn’t have much in common with the real app. I’m not calling .clone() 100k times in one loop in the real world. 😉

My .clone() calls are spread all over the codebase, including the simulation engine where the problem is. It’s thousands of lines, different classes, methods, and getters. It’s not a single 10-100-200 lines block I could easily tweak that way. As usual, it’s performance vs readability and maintainability. I don’t think “caching” vectors would be even possible in my case. I’d rather convert my sim code to use a different math library if I really had to.

Thanks for a quick reply and fix!

Read more comments on GitHub >

github_iconTop Results From Across the Web

Hidden performance implications of Object.defineProperty()
defineProperty () was incurring a performance penalty so using one function call instead of two could cut that down.
Read more >
Object.defineProperties performance "issue" #9536 - GitHub
defineProperty is simnifically faster per each property than bundle all in Object.defineProperties. Although this has done only for 3 properties ...
Read more >
Declaring objects - React Three Fiber Documentation
Constructor arguments. In three.js objects are classes that are instantiated. These classes can receive one-time constructor arguments ( new THREE.
Read more >
SPE.js
@param {Vector3} vec2 Any object that has `x`, `y`, and `z` properties. * @return {SPE.TypedArrayHelper} Instance of this class. */ SPE.
Read more >
Diff - platform/cts - Google Git
n + 3. Verify that the timer named "Start Timer Test" rings after 30 ... score value to a string with at least...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found