Closed
Bug 101964
Opened 24 years ago
Closed 17 years ago
Performance: truncating arrays is slow in SpiderMonkey
Categories
(Core :: JavaScript Engine, defect, P3)
Core
JavaScript Engine
Tracking
()
RESOLVED
WORKSFORME
mozilla1.9alpha1
People
(Reporter: pschwartau, Unassigned)
References
Details
(Keywords: js1.5, perf, Whiteboard: [Mistake in original report; see further down])
Attachments
(2 files, 1 obsolete file)
|
465 bytes,
text/html
|
Details | |
|
806 bytes,
patch
|
Details | Diff | Splinter Review |
Try this in the JS shell:
var BIG = 10000000;
var arr = Array(BIG);
arr.length = 10;
for (var i=0; i<arr.length; i++) {print(i)}
The larger you make the variable BIG, the longer it takes this
program to execute. For the value I have put above, it takes
several seconds.
Simple debugging shows the time is taken on the last line of
the program, not line 2 where the big array is created. I wouldn't
expect the execution of the last line to depend on what BIG is.
Compare: in Rhino, it doesn't matter what the value of BIG is;
the program always takes the same time to execute.
| Reporter | ||
Comment 1•24 years ago
|
||
Similar problem in SpiderMonkey if you access arr.toString() after truncation:
var BIG = 1000000000;
var arr = Array(BIG);
arr.length = 10;
print(arr.toString());
The time it takes to execute the last line depends on the value
of BIG in the first line -
Keywords: js1.5
| Reporter | ||
Comment 2•24 years ago
|
||
I'm assuming this issue is a separate issue from bug 101488,
"Array(m).length = new Number(n) failing (silently)"
| Reporter | ||
Comment 3•24 years ago
|
||
Strange - when I have this testcase in a FILE, and load it in the JS shell,
all the time in SpiderMonkey seems to be taken at the BEGINNING: creating
and truncating the array, rather than in the last step.
Again, this differs from the behavior exhibited by Rhino, where the test
always executes quickly, whether it is interactive or loaded from a file -
| Reporter | ||
Updated•24 years ago
|
Whiteboard: [QA note: test this interactively]
| Reporter | ||
Comment 4•24 years ago
|
||
My mistake - however you try the testcase, all the time is taken up by the
truncation step:
arr.length = 10;
It is this step which takes longer and longer as BIG is increased.
I don't know how but in my interactive test, my debugging code
must have been in the wrong spot.
Resummarizing and keeping bug open, since this performance compares
unfavorably with Rhino -
Keywords: perf
Summary: Truncated arrays act as if they are not truncated → Performance: truncating arrays is slow in SpiderMonkey
Whiteboard: [QA note: test this interactively] → [Mistake in original report; see further down][QA note: test this interactively]
Comment 5•24 years ago
|
||
the following code is where the time is being spent. I'll examine it more
closely.
static JSBool
array_length_setter(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
{
jsuint newlen, oldlen, slot;
jsid id2;
jsval junk;
if (!ValueIsLength(cx, *vp, &newlen))
return JS_FALSE;
if (!js_GetLengthProperty(cx, obj, &oldlen))
return JS_FALSE;
for (slot = newlen; slot < oldlen; slot++) {
if (!IndexToId(cx, slot, &id2))
return JS_FALSE;
if (!OBJ_DELETE_PROPERTY(cx, obj, id2, &junk))
return JS_FALSE;
}
return IndexToValue(cx, newlen, vp);
}
| Reporter | ||
Comment 6•24 years ago
|
||
Testcase added to JS testsuite:
mozilla/js/tests/js1_5/Array/regress-101964.js
Currently it's hard-coded to expect its array truncation to take
no more than 50 ms. Anything longer and the test will fail.
Testcase is currently passing in the rhino and rhinoi shells,
failing in the smdebug and smopt shells -
| Reporter | ||
Updated•24 years ago
|
Whiteboard: [Mistake in original report; see further down][QA note: test this interactively] → [Mistake in original report; see further down]
Comment 7•24 years ago
|
||
This performance bug while valid, will probably not be found in performance
critical programs.
Severity: normal → minor
Status: NEW → RESOLVED
Closed: 24 years ago
Resolution: --- → WONTFIX
| Reporter | ||
Comment 8•24 years ago
|
||
Reopening bug for consideration in JS1.5 final release.
I agree with Kenton that this is not critical, yet I'm wondering
if there might be a not-too-hard fix for this that we could get in.
The testcase for this bug is failing. In the optimized JS shell:
Testcase js1_5/Array/regress-101964.js failed Bug Number 101964
STATUS: Performance: truncating very large arrays should be fast!
Failure messages were:
FAILED!: Expected value 'Truncation took less than 50 ms',
Actual value 'Truncation took 5656 ms'
I will attach an HTML version of this testcase. Here are the
timings (in ms) I get on WinNT(SP6) 500MHz 128M:
IE6 0
NN4 6900
Moz 6700
JS opt 5656
Rhino < 50
Status: RESOLVED → REOPENED
Resolution: WONTFIX → ---
| Reporter | ||
Comment 9•24 years ago
|
||
Comment 10•23 years ago
|
||
Taking for 1.5
/be
Assignee: khanson → brendan
Status: REOPENED → NEW
Priority: -- → P3
Target Milestone: --- → mozilla1.5alpha
Updated•23 years ago
|
Target Milestone: mozilla1.5alpha → mozilla1.6alpha
Updated•22 years ago
|
Target Milestone: mozilla1.6alpha → mozilla1.7alpha
Updated•22 years ago
|
Target Milestone: mozilla1.7alpha → mozilla1.8alpha
Updated•21 years ago
|
Target Milestone: mozilla1.8alpha1 → mozilla1.9alpha
Updated•20 years ago
|
Depends on: native-arrays
Updated•20 years ago
|
Flags: testcase+
Comment 11•20 years ago
|
||
Blake, would you be willing to take this too? It goes along with bug 322889.
/be
Comment 12•20 years ago
|
||
Here's a patch that pulls the essential functionality out of the loop in array_length_setter(). Runtime for the testcase drops from 1600ms to 0ms on my 2.4GHz WinXP box.
I checked for memory leaks, and this change doesn't appear to leak anything.
This is my first patch ever, so please be nice if I'm waaaay off base here.
Comment 13•20 years ago
|
||
Comment on attachment 214407 [details] [diff] [review]
Possible fix
What is this patch doing? It seems to be using a JSJMSG_* constant from liveconnect/*.msg, and it tests for ECMA version in order to throw an exception if non-ECMA, otherwise it doesn't truncate the array. None of that is right. Can you say why you wrote it like this?
/be
Comment 14•20 years ago
|
||
First, I searched for what I thought was the property deletion method that actually gets called from this method (JavaArray_deleteProperty() in jsj_JavaArray.c). It didn't appear that that method actually deletes anything; it just does the same check that I pulled into array_length_setter(). When I test the size of the array after calling the modified array_length_setter, it does come back as the properly truncated size. I figured that we just drop the reference to the memory and trust the garbage collector to clean it up.
This seemed a little simplistic to me and I figured it was wrong, but I wanted to try my hand at an easy bug first. Can you give me a shove in the right direction?
Comment 15•20 years ago
|
||
Upon further review, the earlier patch doesn't compile (I found that I actually compiled with an intermediate version). Here's the patch I actually compiled with.
Attachment #214407 -
Attachment is obsolete: true
Comment 16•20 years ago
|
||
Sorry to say the patches show confusion about very basic stuff:
* JavaScript Array is implemented by js/src/jsarray.c and has nothing to do with java.lang.Array or any such thing.
* js/src/liveconnect is an optional module bridging JS and Java, js/src/js*.[ch] must not include its error message codes.
* The truncation that takes too long with this bug is really required by ECMA-262. We just need to speed up our implementation, not remove the truncation code and violate ECMA.
Please read http://www.mozilla.org/js/language/E262-3.pdf section 15.4.5.1, step 14 in particular.
/be
Comment 17•19 years ago
|
||
Igor, you have "dibs" on this bug. I would be happy to review and advise.
/be
Comment 18•19 years ago
|
||
(In reply to comment #17)
> Igor, you have "dibs" on this bug. I would be happy to review and advise.
Ok, I will have a look after fishing in xml pond stops to bring a catch.
Assignee: brendan → igor.bukanov
Updated•19 years ago
|
QA Contact: pschwartau → general
Comment 19•19 years ago
|
||
Setting the lower bound in array_length_setter from (1<<24) to (1<<16) fixes this bug. It seems like the algorithm in the "else" clause here would be superior for even much smaller arrays, and perfectly acceptable even for tiny arrays. What is the justification for not using it all the time?
Comment 21•17 years ago
|
||
I show this passing on 1.9.0, 1.9.1
Status: NEW → RESOLVED
Closed: 24 years ago → 17 years ago
Resolution: --- → WORKSFORME
You need to log in
before you can comment on or make changes to this bug.
Description
•