JavaScript 引擎性能比较之一SpiderMonkey[通俗易懂]

JavaScript 引擎性能比较之一SpiderMonkey[通俗易懂]1.下载https://people.mozilla.org/~sstangl/mozjs-31.2.0.rc0.tar.bz2bunzip2mozjs-31.2.0.rc0.tar.bz2tarxvfmozjs-31.2.0.rc0.tar2.构建https://developer.mozilla.org/en-US/docs/Mozilla/Projects/

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

JavaScript 是最常用的前端语言, 在后端也渐渐有所应用, 比如 NodeJS, 在C++应用中嵌入JavaScript 到底性能如何?

就拿最流行的 Mozilla SpiderMonkey 和 Google V8 做一个比较测试, 先以 SpiderMonkey 为例, 来执行一个一万个字串的数据排序和反转


1. 下载

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. 构建


https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Build_Documentation




2.1 下载 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 编译步骤


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 编译验证




# ./dist/bin/js


js> print(“hello world”);


hello world


js> quit();




3. 参考资料


*
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. 测试程序

#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 50

using namespace JS;

// The class of the global object.
static JSClass globalClass = { "global", JSCLASS_GLOBAL_FLAGS, JS_PropertyStub,
        JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
        JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, nullptr, nullptr,
        nullptr, 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_t size, const char * restrict format,
        snprintf(arrTimeStr, TIME_FMT_LEN, "%s.%06d", 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 24] 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] = { '\0' };
	    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 callback.
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::DontFireOnNewGlobalHook);
    if (!global)
        return 1;

    // Enter the new global object's compartment.
    JSAutoCompartment ac(cx, global);

    // Populate the global object with the standard globals, like Object and
    // Array.
    if (!JS_InitStandardClasses(cx, global))
        return 1;

    // Your application code here. This may 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;
}

测试JavaScript 脚本

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();

debug_trace("done, first element=" + array[0]+ ", " + "last element=" + array[array.length-1] );

测试结果

$ ./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

性能还可以, 总执行时间花费52 毫秒, JS数组排序反转大约用了4 毫秒多, 下一步看看 Google V8 的表现如何

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/184323.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • idea 集成svn_idea怎么关联svn

    idea 集成svn_idea怎么关联svn当你idea集成svn工具时:依照如下步骤:1.下载并安装svn:链接:https://pan.baidu.com/s/1jIs00Pg密码:2o3x2.特别说明:如果你没选上:那么你会在你的安装路径上无法找到svn.exe3.之后你就可以正常的使用svn。

    2022年10月17日
  • 数字电路实验环境 (Quartus II 9.0)

    数字电路实验环境 (Quartus II 9.0)大家好,我是孙不坚1208,记录一下数字电路这门课的实验环境((QuartusII9.0))安装。所需文件网盘链接:https://pan.baidu.com/s/1VnCc4wR7HAOgxfyWjoUHjw提取码:0kjq安装教程仅限于学习,安装前先关闭各类杀毒软件,注意安装路径不能有中文,存放安装包的路径最好也不要有中文。我们首先在c盘建好相应的文件目录,然后进行安装在此目录下。一、安装QuartusII9.0等它稍微加载,出现下面这个界面。这里进行安装,无脑点击下一步

  • python 2022.01.13 激活【2021最新】

    (python 2022.01.13 激活)本文适用于JetBrains家族所有ide,包括IntelliJidea,phpstorm,webstorm,pycharm,datagrip等。IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.cn/ide…

  • 面试被问到CAS原理,触及知识盲区,脸都绿了!

    面试被问到CAS原理,触及知识盲区,脸都绿了!CAS底层原理想要了解CAS底层原理,那么我们先来了解一下JUC包的一个类即:AtomicInteger。那么这个AtomicInteger有什么用呢?我们平时开发或多或少都会使用到i++这个操作,那么稍微了解多线程的同学都会知道,在多线程环境下,i++操作是线程不安全的操作,譬如下面这段代码:publicclassMain{privateinti=0;publicvoidaddI(){i++;}..

    2022年10月17日
  • ACM计算几何篇_acm数学

    ACM计算几何篇_acm数学1前言1.1计算几何算法1.2计算几何题目特点及要领1.3预备知识2凸包2.1定义2.1.1凸多边形2.1.2凸包2.2颜料配色问题2.2.1问题描述2.2.2问题简化2.2.3问题抽象2.2.4数学抽象2.2.4.1ConvexCombinationAndAffineCombination2.2.4.2区别与联系…

    2022年10月23日
  • dubbo的工作原理[通俗易懂]

    转载地址:https://blog.csdn.net/A_BlackMoon/article/details/85609328dubbo的工作原理1、面试题说一下的dubbo的工作原理?注册中心挂了可以继续通信吗?说说一次rpc请求的流程?2、面试官心里分析MQ、ES、Redis、Dubbo,上来先问你一些思考的问题,原理(kafka高可用架构原理、es分布式架构原理、redis线程模型…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号