views:

67

answers:

2

I am using this bit of code in order to reformat some large ajax responseText into good binary data. It works, albeit slow.

The data that I am working with can be as large as 8-10 megs.

I need to get this code to be absolutely efficient. How would loop unrolling or Duff's device be applied to this code while still keeping my binary data intact, or does anyone see anything that can be changed that would help increase it's speed?

    var ff = [];
var mx = text.length;   
var scc= String.fromCharCode;
for (var z = 0; z < mx; z++) {
    ff[z] = scc(text.charCodeAt(z) & 255);
}
var b = ff.join("");
this.fp=b;
return b;

Thanks Pat

A: 

Convert the data to a JSON array on the server. 8/10 megabytes will take a long time even with a native JSON engine. I'm not sure why a JS application needs 8/10 megs of data in it. If you are downloading to the client's device, convert it to a format they expect and just link to it. They can download and process it themselves then.

Drew
+1  A: 

Your time hog isn't the loop. It's this: ff[z] = scc(text.charCodeAt(z) & 255); Are you incrementally growing ff? That will be a pig, guaranteed.

If you just run it under the debugger and pause it, I bet you will see it in the process of growing ff. Pre-allocate.

Mike Dunlavey
Not saying that couldn't make a difference, but I rather doubt it'll be much of a difference... or an *improvement.* If you have tests that indicate otherwise, you should post them.
Shog9
@Shog9: Perhaps `push` is the best way to add elements. In any case, I suspect the `for` loop is not where the time goes.
Mike Dunlavey
@Mike: I agree with you WRT the loop bit not being a big factor. Array performance varies widely across browsers (even between browser versions), as does the relative performance of string concatenation vs. array.join(). I'd like to see some more information from the OP as to where he's running this and how slow it's actually running for him - I rather suspect he could improve matters *dramatically* by switching to a regexp (native code all the way).
Shog9
@Shog9: It is being run in a webos mobile app. It runs without a glitch on the emulator on my mac, however on the actual mobile device, it freezes. So I figured that a more optimized version of the code snippet or a logic change from using a for/loop to using an unrolling mechanism, may help. The code was developed from the, Handling of Binary, section of this mozilla page: https://developer.mozilla.org/en/Using_XMLHttpRequest which offers this to handle binary data from an ajax request: var abyte = filestream.charCodeAt(x) I need to iterate the entire ajax responseText. Any advice?
cube
@cube: We always hear on SO lines like: "it freezes. So I figured ... XXX ... may help". It might, or it might not, because you don't *know* that it will. Like if you compare linear search to binary search. Linear search is picking elements only because they "might" be right. Binary search makes decisions based on actual information. You need to do the same. If the app seems to freeze, then you're in luck, because that makes it extremely easy to find out why, by this method: http://stackoverflow.com/questions/3743504/any-references-on-dynamic-code-analysis/3745797#3745797
Mike Dunlavey
@Mike: you stated in yor answer above, "Pre-allocate", what eactly do you mean by that? Could you give me a code example, please? Thanks.
cube
@cube: In most languages, if you have a self-growing array, it grows when you set an element outside its current size. Growing means it has to allocate a new array larger than the old, copy the old data into it, and release the old array. That can happen a *lot*. So if you can give the array the desired size to begin with, you can avoid all that. However, they tell me that js arrays might be smarter than that, and be optimized for the *push* operation. But still, if you can size it to begin with, setting `ff[z]` has to be faster. Regardless, I would really try to interrupt it.
Mike Dunlavey
ok, I see what you are saying. So in my case, I would do `var ff=[xxxxxxx]` to initialize it. Where xx being the responseText length from the ajax call. Correct?
cube
@cube: I'm hoping you can do something like that, because I'm not a js expert. Also, I hope you got the point that if there is some way to interrupt it while it's running, at a random time of your choosing, and if you can see its call stack, since it is spending a lot of time doing what it shouldn't do, you're almost certain to catch it in the act, and the stack will tell you exactly what it's doing. So if most of its time is spent growing `ff`, you will see it in the act of doing that.
Mike Dunlavey
Thank you, Mike. I will run it through firebug and see what comes up.
cube