JavaScript is the most commonly used front-end language, and has been used in the backend, such as NodeJS, what is the performance of embedding JavaScript in C + + applications?
Take the most popular Mozilla SpiderMonkey and Google V8 to do a comparison test, first take SpiderMonkey as an example, to perform a 10,000 string of data sorting and inversion
1. Download
https://people.mozilla.org/~sstangl/mozjs-31.2.0.rc0.tar.bz2
bunzip2 mozjs-31.2.0.rc0.tar.bz2
Tar xvf mozjs-31.2.0.rc0.tar
2. Build
Https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Build_Documentation
2.1 Downloads autoconf2.13
Http://ftp.gnu.org/gnu/autoconf/autoconf-2.13.tar.gz
tar xvfz autoconf-2.13.tar.gz
./configure--prefix=/usr--program-suffix=-2.13
Make acdatadir=/usr/share/autoconf-2.13
Make acdatadir=/usr/share/autoconf-2.13 Install
2.2 Compilation Steps
CD JS/SRC
autoconf-2.13
# This name should end with "_opt. OBJ "To make the version control system ignore it.
mkdir build_opt. OBJ
CD build_opt. OBJ
.. /configure
# Use ' Mozmake ' on Windows
Make
Make Install
------------
.. /.. /dist/bin/nsinstall-t Js-config/usr/local/bin
.. /.. /dist/bin/nsinstall-t Libjs_static.a/usr/local/lib
mv-f/usr/local/lib/libjs_static.a/usr/local/lib/libmozjs-31.a
.. /.. /dist/bin/nsinstall-t Libmozjs-31.dylib/usr/local/lib
/applications/xcode.app/contents/developer/usr/bin/make-c Shell Install
.. /.. /.. /dist/bin/nsinstall-t Js/usr/local/bin
------------
2.3 Compilation Verification
#./dist/bin/js
js> print ("Hello World");
Hello World
js> quit ();
3. References
*Https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/JSAPI_User_Guide
*Https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/How_to_embed_the_JavaScript_engine
4. Test Procedures
#include "jsapi.h" #include <stdio.h> #include <stdlib.h> #include <sys/time.h> #include <time.h > #include <unistd.h> #define Trace_minargs 2#define Time_fmt_len 50using namespace js;//The class of the global O Bject.static Jsclass Globalclass = {"Global", Jsclass_global_flags, Js_propertystub, Js_deletepropertystub, JS_Pro Pertystub, Js_strictpropertystub, Js_enumeratestub, Js_resolvestub, Js_convertstub, nullptr, nullptr, Nullpt R, nullptr, Js_globalobjecttracehook};long long Current_timestamp (char Arrtimestr[time_fmt_len]) {struct Timeval TV; struct tm* ptm; Char time_string[40]; Gettimeofday (&TV, NULL); Get current time if (arrtimestr) {ptm = LocalTime (&tv.tv_sec); /* Format The date and time, down to a single second. */strftime (time_string, sizeof (time_string), "%y-%m-%d%h:%m:%s", PTM); /* Compute milliseconds from microseconds. *///snprintf (char * restrict str, size_tSize, const char * restrict format, snprintf (Arrtimestr, Time_fmt_len, "%s.%0 6d ", time_string, tv.tv_usec); } Long Long Total_us = tv.tv_sec * 1000000LL + tv.tv_usec; Caculate milliseconds//printf ("milliseconds:%lld\n", milliseconds); return Total_us;} [SpiderMonkey] Use Jsbool instead of bool.static bool Debug_trace (jscontext *cx, unsigned argc, Jsval *vp) {JS:: Callargs args = CALLARGSFROMVP (argc, VP); if (args.length () > 0) {char Sztimestr[time_fmt_len] = {'} '}; Current_timestamp (SZTIMESTR); Jsstring *str = args[0].tostring (); printf ("[%s]%s\n", Sztimestr, Js_encodestring (CX, str)); } return true; typedef void (* Jserrorreporter) (Jscontext *cx, const char *message, Jserrorreport *report);//the error reporter Callba Ck.void Report_error (Jscontext *cx, const char *message, Jserrorreport *report) {fprintf (stderr, "%s:%u:%s\n", Report->filename? Report->filename: "[no filename]", (unsigned int) report->lineno, message);} int Load_file_malloc (const char* szfile, char*& pbuffer, long* pbufsize = null) {file * pFile = null; Long lsize = 0; size_t result = 0; PFile = fopen (Szfile, "R"); if (PFile = = NULL) {fputs ("File open Error", stderr); return 1; }//Obtain file Size:fseek (pFile, 0, seek_end); lsize = Ftell (pFile); Rewind (PFile); Allocate memory to contain the whole File:pbuffer = (char*) malloc (sizeof (char) * lsize); if (pbuffer = = NULL) {fputs ("Memory allocate Error", stderr); Fclose (PFile); return 2; }//Copy the file into the Buffer:result = Fread (pbuffer, 1, lsize, pFile); if (Result! = lsize) {fputs ("Reading file Error", stderr); Fclose (PFile); return 3; } if (pbufsize) *pbufsize = lsize; Fclose (PFile); return 0;} int Test (Jscontext *cx, rootedobject* pglobal, const char* pscript) {//rootedobject GlobaL = *pglobal; Js::rootedvalue Rval (CX); Jsautocompartment ac (CX, *pglobal); Js_initstandardclasses (CX, *pglobal); const char *filename = "Noname"; int Lineno = 1; bool OK = js_definefunction (cx, *pglobal, "Debug_trace", Debug_trace, Trace_minargs, 0); if (!ok) return 1; OK = Js_evaluatescript (cx, *pglobal, Pscript, strlen (pscript), filename, Lineno, &rval); if (!ok) return 2; Jsstring *str = rval.tostring (); printf ("%s\n", js_encodestring (CX, str)); return 0;} int run (Jscontext *cx, const char* pscript) {//Enter a request before running anything in the context. Jsautorequest ar (CX); Create the global object and a new compartment. Rootedobject Global (CX); Global = Js_newglobalobject (CX, &globalclass, nullptr, JS::D ontfireonnewglobalhook); if (!global) return 1; Enter the new Global object ' s compartment. Jsautocompartment AC (CX, Global); Populate theGlobal object with the Globals, like object and//Array. if (! Js_initstandardclasses (CX, Global)) return 1; Your application code here. This could include JSAPI calls to create your//own custom JS objects and run scripts. Long Long begin_time = Current_timestamp (NULL); Test (CX, &global, pscript); Long Long end_time = Current_timestamp (NULL); printf ("Calling costs%lld microseconds\n", end_time-begin_time); return 0;} int main (int argc, const char *argv[]) {//Initialize the JS engine. if (! Js_init ()) return 1; Create a JS runtime. Jsruntime *rt = js_newruntime (8L * 1024L * 1024L, js_use_helper_threads); if (!RT) return 1; Create a context. Jscontext *cx = Js_newcontext (RT, 8192); if (!CX) return 1; Js_seterrorreporter (jscontext *cx, jserrorreporter er); Js_seterrorreporter (CX, report_error); int status = 0; if (argc > 1) {char* buffer = NULL; int ret = Load_file_malloc (argv[1], buffer); if (ret! = 0) {return ret; } status = Run (cx, buffer); Free if (buffer) free (buffer); } else {const char *script = "' Hello ' + ' world, it is ' +new Date ()"; Status = Run (CX, script); }//Shut everything down. Js_destroycontext (CX); Js_destroyruntime (RT); Js_shutdown (); return status;}
Test JavaScript scripts
function Random_str () { var text = ""; var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; for (var i=0; i < 8; i++) text + = Possible.charat (Math.floor (Math.random () * possible.length)) ; return text;} var array = new Array (), for (var i = 0; i < 10000; i++) {Array[array.length] = Random_str ();} Debug_trace ("Begin sort and reverse array which length=" + array.length); Array.Sort (); Array.reverse ();d ebug_trace (" Done, First element= "+ array[0]+", "+" last element= "+ array[array.length-1]);
Test results
$./test/spidermonkeytest./test/arraysort.js
[2015-05-07 21:07:29.762895] begin sort and reverse array which length=10000
[2015-05-07 21:07:29.766270] done, first ELEMENT=ZZJG0PNH, last Element=0000lzbe
Calling costs 52492 microseconds
Performance is still, about 4 milliseconds, next step to see how Google V8 Performance
One of the JavaScript engine performance comparisons SpiderMonkey