[SERVER-20019] investigate SpiderMonkey performance degradation vs. v8 Created: 18/Aug/15  Updated: 02/Aug/18  Resolved: 24/Aug/15

Status: Closed
Project: Core Server
Component/s: JavaScript, Performance, Shell
Affects Version/s: None
Fix Version/s: 3.1.8

Type: Task Priority: Major - P3
Reporter: Adam Midvidy Assignee: Gregory McKeon (Inactive)
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Backwards Compatibility: Fully Compatible
Participants:

 Comments   
Comment by Githook User [ 24/Aug/15 ]

Author:

{u'username': u'thecalvinchan', u'name': u'Calvin Chan', u'email': u'calvin.chan.h@gmail.com'}

Message: SERVER-20019 SpiderMonkey performance improvement in shell by removing pre-emptive string creation

The current SpiderMonkey implementation preemptively generates a string
for the IdWrapper of JSid. This id->std::string conversion is expensive
and is quite often unnecessary. By delaying the creation of the string
until after checking that it is absolutely necessary, we can improve
SpiderMonkey performance on the shell by about 20%.

Signed-off-by: Adam Midvidy <amidvidy@gmail.com>
Branch: master
https://github.com/mongodb/mongo/commit/d62950018b994a989dded40d677ebd578dfcf33d

Comment by Mira Carey [ 19/Aug/15 ]

To add in some background:

It's fairly expected that id -> std::string conversions are expensive. V8 used utf8 strings internally, so going in and out of javascript was fairly inexpensive (just a copy). In comparison, spidermonkey has utf16 strings (so we have encode/decode added into the mix).

If you wanted to take a stab at the particular cost center you identified, you might try delaying the:

// scripting/mozjs/db.cpp DBInfo::getProperty
std::string sname = IdWrapper(cx, id).toString();

Line, until after we've identified that we don't have it already. We're probably just making the string "_db" over and over again (at least looking at the bulk api).

We could also probably skip making the string until after we've checked to see if it's empty or has a leading '_' by just using the mozilla string functions on a JSString*

Comment by Margaret Stephenson [ 19/Aug/15 ]

In addition, about 14.7% of the time spent in Interpret is used by ValueWriter::toBSON, which is called by MongoBase::Functions::wrapper_find and MongoBase::Functions::wrapper_bsonsize during the Invoke stage of Interpret.

Comment by Calvin Chan [ 19/Aug/15 ]

Ran some basic profiling tests. In one case, running the provided function in SERVER-19977 on SpiderMonkey yielded a total running time of approx. 10 seconds.

98% of the time is spent inside SpiderMonkey's Interpret function (third_party/mozjs-38/extract/js/src/vm/Interpreter.cpp). Within that it seems like the biggest culprit is the invocation of IdWrapper::toString() inside DBInfo::getProperty (mongo/scripting/mozjs/db.cpp).

IdWrapper::toString is called multiple times, and for the majority of the times it contributes a significant amount to the overall running time, largely due to the construction of the mozjs::JSStringWrapper

Generated at Thu Feb 08 03:52:54 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.