优化QScriptEngine重复操作

时间:2014-02-15 14:41:16

标签: javascript c++ qt optimization qtscript

我正在尝试在我的一个函数中优化QScriptEngine操作。

该函数名为executeCustomJSOperation,它在多个文件中执行相同的JS代码。但是,每个文件都需要更改名为$xmlData的全局变量。该函数基本上使用$xmlData变量将XML文件加载到内存中,然后始终应用相同的javascript代码(jsString)来使用javascript编辑此XML文件。最后,$xmlData变量再次使用编辑过的XML进行更新。

我只使用OpenMP parallel for而不是处理每个XML文件的for循环获得2.5加速。但现在我不知道如何进一步提高这个功能的速度。

代码如下:

// allows user to echo js variables to check them in terminal using cout
QScriptValue echo(QScriptContext *context, QScriptEngine *engine)
{
    std::cout << context->argument(0).toString().toUtf8().constData() << std::endl; 
    return "";
}

void executeCustomJSOperation(const QString &jsString, const QStringList &filesToProcess){  
    QString rexmlString, jsxmlString;
    QFile rexmlfile(":/resources/libs/rexml.js"); // load javascript libraries as strings to memory
    QFile jsxmlfile(":/resources/libs/jsxml.js");

    rexmlfile.open(QFile::ReadOnly | QFile::Text);
    jsxmlfile.open(QFile::ReadOnly | QFile::Text);

    rexmlString=QTextStream(&rexmlfile).readAll();
    jsxmlString=QTextStream(&jsxmlfile).readAll();

    // Process all XmlFiles
#pragma omp parallel for // 2.5 speedup in my pc
    for(int i=0; i<filesToProcess.size(); i++){

        QString currXmlFileString;

        QScriptEngine engine;
        QScriptValue engineResult;

        // Add echo function so user can debug the code
        QScriptValue echoFunction = engine.newFunction(echo);
        engine.globalObject().setProperty("echo", echoFunction);

        engine.evaluate(rexmlString); // load js libraries in js engine
        engine.evaluate(jsxmlString);

        QFile currXmlFile(filesToProcess[i]);

        currXmlFileString=QTextStream(&currXmlFile).readAll();

        currXmlFile.close(); // close reading

        engine.globalObject().setProperty("$xmlData",currXmlFileString);

        engine.evaluate("main(); function main() {"+jsString+"}"); // main function allows to use return to exit prematurely from user code

        engineResult=engine.globalObject().property("$xmlData");

        QTextStream(&currXmlFile) << engineResult.toString(); // retreive the modified xml by javascript and save it to the file
    }
}

您认为可以进一步优化此代码吗?如果您有任何疑问,请询问。

2 个答案:

答案 0 :(得分:1)

您可以构造一个QScriptProgram,将所有JS代码放入其中并使用QScriptEngine::evaluate对其进行评估。它可以加快执行速度,因为解析JS代码只会执行一次。但是,QScriptProgram未记录为可重入或线程安全,因此即使每个线程都使用自己的QScriptProgram对象,也无法确定它是否可以在多个线程中正常工作。

答案 1 :(得分:1)

为什么要为每次迭代创建/初始化单独的QScriptEngine?我建议将所有内容移到您的行中

engine.evaluate(jsxmlString);

for()-loop之外。

没错,这会使WRT线程变得更加困难。基本上,您必须设置 n 工作线程,并为每个线程(不是每个文件)创建一个脚本引擎。对于初学者来说,一个简单的单线程版本应该让你初步了解预期的加速比,以及这是否值得。

当然,如果您的JS代码真的仅供一次使用,那么QScriptProgram是您唯一的优化希望。同样,您需要设置有限数量的工作线程,每个线程都有自己的QScriptProgram(每次迭代一次QScriptEngine,就像您当前的代码一样。)