Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

JS Optimization

Name: Anonymous 2011-09-12 5:05

After profiling, I see that roughly 25-30% of my program's time is spent inside this function.

Unfortunately, this isn't my algorithm, and I don't think I can improve it. The paper it came from is here: http://www.dgp.toronto.edu/people/stam/reality/Research/pdf/GDC03.pdf

My only option seems to be "performance tricks", but I don't see any openings. The only thing I can say for sure that I haven't tried is ``loop unrolling'', but I don't have much experience doing that myself, and I don't see how I could do it here while staying in bounds. If it helps, height, width, and iterations are all set by the user.

So: any ideas on how to improve the performance of this code?

function lin_solve(b, x, x0, a, c) {
        if (a === 0 && c === 1) {
            for (var j = 1; j <= height; j++) {
                var currentRow = j * rowSize;
                ++currentRow;
        var i = width - 1; do {
                    x[currentRow] = x0[currentRow];
                    ++currentRow;
                } while (i--);
            }
            set_bnd(b, x);
        } else {
            var invC = 1 / c;
            for (var k = 0; k < iterations; k++) {
                for (var j = 1; j <= height; j++) {
                    var lastRow = (j - 1) * rowSize;
                    var currentRow = j * rowSize;
                    var nextRow = (j + 1) * rowSize;
                    var lastX = x[currentRow];
                    ++currentRow;
                   
            var i = width; do {
                        lastX = x[currentRow] = (x0[currentRow] + a*(lastX+x[++currentRow]+x[++lastRow]+x[++nextRow])) * invC;
            } while (i-- > 1)
                }
                set_bnd(b, x);
            }
        }
    }

Name: Anonymous 2011-09-14 23:56

(Actually it's (x0[11] + a * (x[10] + x[12] + x[1] + x[21])) * invC; I forgot the parentheses accidentally.)

Name: Anonymous 2011-09-15 0:33

>>40
I don't know if that's the same in other C-like languages
who gives a fuck, this is javascript!

enjoy your broken ==

Name: Anonymous 2011-09-15 2:38

>>42

I use ===

Name: Anonymous 2011-09-15 10:44

>>43
The forced usage of the identity operator

Name: Anonymous 2011-09-17 3:21

10 things I've learned about writing efficient JS

1. On my setup, for is faster than while and do...while, even when you do it in reverse and take out the comparison operators (http://jsperf.com/loop-comparison). Maybe that's not true for other people, but that it's possible at all makes me think that the rationale for using do while in the first place is bullshit. Add to this dubious performance gain the extra effort incurred by ensuring that your loop works backwards as well as forwards, and finally I reach the conclusion that this advice needs to stop. for with cached length is as good as you can get, even when you're trying to wring every last drop out of your loops.

2. If your loop optimization idea requires that you add a conditional inside the loop, then it's probably not an optimization. That shit is really slow.

3. Use bitwise math for floor/ceil/round on positive Numbers. You can throw in a | 0 or a + 0.5 | 0 for free, basically. Meanwhile, Math.round() is way more expensive than it should be.

4. Google tools: Google Closure makes code smaller, not faster. And ADVANCED_MODE requires that you write Javascript like a Java programmer. However, Google also has the fastest Javascript engine and the clearest profiler in Chrome. They also have ``Speed Tracer'', which profiles the entire page from within the browser, showing you how much is spent on paint, layout, etc. (http://code.google.com/webtoolkit/speedtracer/)

5. Incrementing operators (++, --) are evaluated from left to right in a chain of assignments -- not right to left, and not by nested parentheses. Since this is obtuse, it would be better if you didn't use these inside complex operations.

6. Heavy closure nesting doesn't affect the performance of the innermost closure by default, as outside variables are only looked up if they're used inside the closure. Same goes for "special" variables like arguments -- performance takes a hit when you use these, as you should expect with anything that resembles reflection.

A little trick: if your code uses the DOM, add window, documentas arguments to your instantly-executed (function(){...})() wrapper, with window and window.document as the passed arguments.

7. Object chains do matter, the interpreter has to climb the chain every time you call a method. It's better to cache the function first in performance-critical areas.

(I'm not sure if the interpreter has to climb up the closure nodes every time when using a closed over variable in the same way that it has to climb down the object nodes, but it stands to reason.)

8. Array() is never faster, not even if you're using it to allocate the memory ahead of time with a known size.

9. innerHTML works faster if you have no elements to destroy when you make your change. Therefore, if you don't care about losing bound events, you should clone the element first:
var clone = DOMElement.cloneNode(false);
clone.innerHTML = /* stuff */;
DOMElement.parentNode.replaceChild(clone, DOMElement);
DOMElement = clone;


10. apply allows you to call a function and pass an array as its arguments. Therefore, any native function that takes variable arguments can be called with an array you're using. Ex: Math.max.apply( Math, array );

Welp. My "optimized" version with ``flattened loops'' eventually earned me 20 less frames a second. My blind fervor in trying to get rid of mults caused me to bloat out my loops, with the added benefit of making everything harder to read. I had to throw it out and start over. This time I'm going to avoid some of the obviously bad decisions.

P.S. Stupid shit I learned that I should have known already:
1. Modulo and division are slower than multiplication
2. Loop invariants multiplied by loop incrementors can be replaced with addition
3. Loop incrementor comparison:
var len = 10, i;
console.log('for'); for (i = 0; i < 10; i++) console.log(i); // 0-9
console.log('while i++'); i = 0; while(i++ < len) console.log(i); // 1-10
console.log('while ++i'); i = 0; while(++i < len) console.log(i); // 1-9
console.log('while i--'); i = len; while(i--) console.log(i); // 9-0
console.log('while --i'); i = len; while(--i) console.log(i); // 9-1
console.log('do while i--'); i = len; do { console.log(i) } while(i--); // 10-0
console.log('do while --i');i = len; do { console.log(i) } while(--i); // 10-1
console.log('do while len-1 i--');i = len - 1; do { console.log(i) } while(i--); // 9-0
console.log('do while len-1 i--');i = len - 1; do { console.log(i) } while(--i); // 9-1

Name: Anonymous 2011-09-17 4:20

>>44

PHP is the same :<

Newer Posts
Don't change these.
Name: Email:
Entire Thread Thread List