1
\$\begingroup\$

Please note that a similar question has been asked before in the context of C#.

Say I'm building a 3D game in Javascript or Actionscript, and doing a lot of 3D vector math. In current libraries, every operation causes a new object to be created and returned as the result value. What is a simple way to optimize this?

For example in this snippet, 2 new Vector3D objects are created, one at the divide and one at the multiply operator.

// JS
result = v.divideBy(len1).multiplyBy(len2);

A better approach would be creating a single object and reusing it.

// JS
var _temp = {x:0, y:0, z:0};  // create a single object once
....
v.divideBy(len1, _temp);       // re-use it
_temp.multiplyBy(len2, _temp); // re-use it

In C# you could just use structs, but in languages like JS and AS3 there are no such things. What does one do to minimise object creation in such languages?

Edit: For example currently I'm doing BSP partitioning in the browser, and its very slow during the BSP operation. (I have profiled to confirm this) I have discovered that the major cause is vector math, and the GC that occurs often that also causes stutters.

Edit: Please note that my question can apply to any type of object in general, not just vector math. So when I'm creating millions of objects as a return value of any function, performance would be affected. Therefore, I am looking for better design patterns to solve the very common issue of returning multiple values.

\$\endgroup\$
2
  • \$\begingroup\$ I am not a JS expert, but the same idea of reusing an object can be extended, in other words use object pools.. \$\endgroup\$
    – concept3d
    Commented Oct 20, 2015 at 14:21
  • \$\begingroup\$ Part of the problem, then, is your libraries aren't very efficient. Also, what concept3d said. I guess there might be the option of calling into native libraries to do math really quickly via e.g. linmath.h written in C... IIRC both the Flash runtime and browser-based JS have this capability; but portability may be an issue. \$\endgroup\$
    – Engineer
    Commented Oct 20, 2015 at 14:35

2 Answers 2

2
\$\begingroup\$

A possible approach that could be very quick is to create one or more webworkers for your computational tasks. A webworker doesn't share any memory with the main thread or other webworker, so it won't pollute the global memory.

If you need a quick and dirty solution without much rewriting or choosing another library, you could try it that way.

P.S.: I would have liked to add this as a comment, but can't due to missing reputation.

\$\endgroup\$
1
\$\begingroup\$

As with your other question, I think you need to profile your code and assess the bottlenecks. Languages like Javascript, which perform significant allocations by design of the language, have efficient allocators and garbage collectors. I would argue that the design of your library is wrong. There are a number of effective libraries out there that use the same syntax. Here's one: http://sylvester.jcoglan.com/

And sample syntax:

var V1 = $V([3,4,5]);
var V2 = $V([9,-3,0]);

var d = V1.dot(V2);
// d is 15

var c = V1.cross(V2);
// c is the vector (15,45,-45)

or http://victorjs.org

var vec1 = new Victor(100, 100);
var vec2 = new Victor(200, 200);

vec1.dot(vec2);
// => 40000

Simply citing a language's need to allocate temporaries isn't fair when a language is designed around fast, generational allocations and garbage collectors, as you'll find in modern javascript implementations. I would go and profile where the bottlenecks are and be sure it is the allocations, first.

\$\endgroup\$
2
  • \$\begingroup\$ And why is the "design of my library wrong"? .. I'm doing the same thing the libraries you cited are... whats the difference? Dot product is a really simple op, you are simply returning a number/int. No performance hit. Cross product is more interesting, and does return a new object. Or am I misunderstanding something? \$\endgroup\$ Commented Oct 22, 2015 at 16:34
  • \$\begingroup\$ Cross product returns a new object : github.com/jcoglan/sylvester/blob/master/src/vector.js#L127 \$\endgroup\$ Commented Oct 22, 2015 at 16:35

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .