1

バックグラウンド: 私は、以下を必要とするプロジェクトで作業しています: ユーザーは、メイン プログラム (Qt/C++ で記述された GUI) の内部変数を使用していくつかの数学演算を実行するコマンドを記述できます。

私のアプローチは、ユーザーが JavaScript でコマンド/スクリプトを記述できるテキスト ボックスで、Qt がそのコードを評価します。そのために私はQJSEngineを使用しています

問題: JavaScript の計算速度が非常に遅い/遅い。

たとえば、2 つのテキスト ボックス (QTextEdit) と 1 つのボタンを備えた GUI があります。ユーザーが 1 つのテキスト ボックスに JavaScript コードを記述し、ボタンが押されると評価され、結果がもう 1 つのテキスト ボックスに表示されます。

悪いパフォーマンスの例として、ユーザーがこの些細な JavaScript コードを書くと、コンピューターは答えを表示するのに約 3 秒かかります。

var X = [];
for (var i=0 ; i < 934600 ; ++i )
{
   X[i] = i;
}
X[120]

一方、Qt/C++ で同じ操作を実行すると、「瞬時に」次のようになります。

QVector<double> myVec;
for(int i=0; i < 934600; ++i)
{
  myVec.append(i);
}
qDebug() << myVec.value(120);

JavaScript がインタープリター言語であることは知っていますが、このパフォーマンスは正常ですか?

ここに、この問題を示す小さな Qt サンプル プログラム (pr_Parser) があります。これを Qt Creator 4.0.1 でテストしました。Qt 5.7 MSVC2013 64 ビット。

ありがとうございました。

pr_parser.pro

QT       += core gui qml    
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets    
TARGET = pr_Parser
TEMPLATE = app    
CONFIG += c++11    
SOURCES += main.cpp\
        CMainWindow.cpp    
HEADERS  += CMainWindow.h

main.cpp

#include "CMainWindow.h"
#include <QApplication>    
int main(int argc, char *argv[])
{
   QApplication a(argc, argv);
   CMainWindow w;
   w.show();
   return a.exec();
}

CMainWindow.h

#include <QMainWindow>
class QPlainTextEdit;    
class CMainWindow : public QMainWindow
{
   Q_OBJECT

public:
   CMainWindow(QWidget *parent = 0);
   ~CMainWindow();    
private:
   QPlainTextEdit *m_p_myScriptWindow;
   QPlainTextEdit *m_p_myResultWindow;    
private slots:
   void slot_ExecuteScript();
};

CMainWindow.cpp

#include "CMainWindow.h"
#include <QtWidgets>
#include <QJSEngine>

    CMainWindow::CMainWindow(QWidget *parent)
   : QMainWindow(parent)
{
   QWidget *window = new QWidget(this);
   setCentralWidget(window);
   QString sampleScript = "var X = [];";
   sampleScript.append("for (var i=0 ; i < 934600 ; ++i ){X[i]=i;}");
   sampleScript.append("X[120]");
   m_p_myScriptWindow = new QPlainTextEdit(sampleScript, this);
   m_p_myResultWindow = new QPlainTextEdit(this);
   QPushButton *myButton = new QPushButton("Execute", this);
   QVBoxLayout *myLayout = new QVBoxLayout(this);
   myLayout->addWidget(m_p_myScriptWindow);
   myLayout->addWidget(myButton);
   myLayout->addWidget(m_p_myResultWindow);
   window->setLayout(myLayout);
   connect(myButton, SIGNAL(clicked()), this, SLOT(slot_ExecuteScript()));
}

CMainWindow::~CMainWindow(){}

void CMainWindow::slot_ExecuteScript()
{
   QJSEngine myEngine;
   QString myScript = m_p_myScriptWindow->toPlainText();
   QJSValue myValue = myEngine.evaluate(myScript);
   if(myValue.isError())
   {
    m_p_myResultWindow->setPlainText(myValue.property("message").toString());
   }
   else
   {
      m_p_myResultWindow->setPlainText(myValue.toString());
   }

   // This code is "instanteneous"
   // QVector<double> myVec;
   // for(int i=0; i < 934600; ++i) {myVec.append(i);}
   // m_p_myResultWindow->setPlainText(QString::number(myVec.value(120)));
}
4

1 に答える 1

0

私は答えを見つけました。

問題は、デバッグ モードでコンパイルしていたことです。リリースモードでは 10 倍速くなります。

数回実行した測定時間 (QElapsedTimer を使用):

JavaScript スクリプト:

  • デバッグモード時:2900~3000ms
  • リリースモード時:255~300ms

ネイティブ Qt/C++ の同じ「for」:

  • デバッグモード時:26~29ms
  • リリースモード時:7~6ms
于 2016-10-05T11:14:01.780 に答える