2014-02-15 9 views
0

내 함수 중 하나에서 QScriptEngine 연산을 최적화하려고합니다.QScriptEngine 반복 동작 최적화

이 함수의 이름은 executeCustomJSOperation이며 여러 파일에서 동일한 JS 코드를 실행합니다. 그러나 각 파일은 $xmlData이라는 전역 변수를 변경해야합니다. 기본 함수는 $xmlData 변수를 사용하여 XML 파일을 메모리에로드 한 다음 항상 동일한 자바 스크립트 코드 (jsString)를 적용하여 javascript를 사용하여이 XML 파일을 편집합니다. 결국 $xmlData 변수가 편집 된 XML로 다시 업데이트됩니다.

각 XML 파일을 처리하는 for 루프보다 OpenMP parallel 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 
    } 
} 

당신은 더이 코드를 최적화 할 수 있습니다 생각하십니까 :

코드는 다음과 같다? 의심스러운 점이 있으면 물어보십시오.

답변

1

왜 각 반복마다 별도의 QScriptEngine을 만들고 초기화합니까? 나는 당신의 라인 for()-loop 외부로

engine.evaluate(jsxmlString); 

에 모든 것을 움직이는 게 좋을 것.

참, 이것은 상황을 더 어렵게 만들 것입니다. 기본적으로 n 작업자 스레드를 설정하고 스레드 당 하나의 스크립트 엔진을 생성해야합니다 (파일 당 아님). 처음에는 단순한 단일 스레드 버전이 어떤 속도 향상이 예상되는지, 그리고 그럴만 한 가치가 있는지에 대한 첫 번째 아이디어를 제공해야합니다.

물론 JS 코드 이 실제로 일회 사용 인 경우에만 QScriptProgram이 유일한 최적화 대상입니다. 다시 말하지만, 제한된 수의 작업자 스레드를 설정하고 각각은 QScriptProgram (현재 코드에서와 같이 반복 당 하나의 QScriptEngine)가됩니다.

+0

감사! 시간과 관련된 변경 사항을 잠시 동안 업데이트하지 않았습니다. 당신이 제안한 것과 똑같이 썼습니다. 스레드 당 하나의 QScriptEngine 만 만들고 중복 코드를 루프 밖으로 옮겼습니다. 나는 측정을하지 않았지만 나는 더 빠름을 안다. QScriptProgram 팁을 시도했지만 성능에 큰 변화가 없다는 것을 알았습니다. QScriptProgram을 각 스레드가 사용하는 힙의 벡터에 할당하고 있습니다. 나는 또한'V8' JSengine을 사용한다고 믿는 새로운'QJSEngine'을 시도했지만 느린 결과를 얻었습니다. : | – RandomGuy

1

QScriptProgram을 구성하고 모든 JS 코드를 넣은 다음 QScriptEngine::evaluate을 사용하여 평가할 수 있습니다. JS 코드 파싱은 한 번만 수행되기 때문에 실행 속도가 빨라질 수 있습니다. 그러나 QScriptProgram은 재진입 성 또는 스레드 안전성으로 문서화되어 있지 않으므로 각 스레드가 고유 한 QScriptProgram 개체를 사용하더라도 여러 스레드에서 올바르게 작동하는지 확신 할 수 없습니다.

+0

안녕하세요, 팁 주셔서 감사합니다. 나는 그것을 시도했지만 나는 그것으로 CPU 성능을 향상시킬 수 없었다. 또한'QScriptProgram'은 쓰레드에 안전하지 않으므로 생성 후에 js를 파싱하는 각 쓰레드에 하나를 사용하지 않는다면 쓰레드와 함께 사용할 수 없다고 말했습니다. 나는 또한 모든 스레드에 대해 같은 객체 (qengine 및 qscriptprogram 포함)를 사용해 보았으며이 때문에 omp critical, qmutex 및 EnterCriticalSection과 같은 동기화 방법을 시도했지만 프로그램이 너무 느려졌다. 지금까지 가장 빠른 구현은 각 스레드가 개별 엔진/변수를 가지고있는 곳에 게시했습니다. – RandomGuy

+0

JS 코드에서 하나의'QScriptProgram' 파일을 생성하고, 그 파일을 여러 장 만들고 (저렴한 파일이어야 함) 모든 스레드에 배포하십시오. –

+0

불행히도 옵션이 스레드와 함께 작동하지 않는 것 같습니다. 내가 그 방법을 사용할 때 세분화 오류가 발생합니다. 'QScriptProgram :: QScriptProgram (const QScriptProgram & other)'생성자가 QScriptProgram의 전체 복사본을 만들지 못하는 것 같습니다. 구현 된 코드 [여기] (http://pastebin.com/6n4urL0G)를 확인할 수 있습니다. 이 코드에는 여기에 게시 된 단순화 된 코드뿐만 아니라 전체 코드도 포함됩니다 (예를 들어 오류 검사 포함). – RandomGuy