Qt 4.6 の Technology Preview 1が出たので、ビルドしてみました。もちろん目当てはDOM APIが整備されたQtWebKitです。以前はevaluateJavaScriptというメソッドを経由してDOMをいじらないといけなかったので、速度・使い勝手的に厳しいものがありましたが、今回ははたしてどうでしょう?コードはこんな感じ:
void MainWindow::on_actionDOM_API_triggered()
{
//DOM API版
int i;
QTime t;
t.start();
//本当は比較のためdocument.createElementと同等なAPIを使うべきだが見つからないので仕方なく断片の文字列を読み込ませている
for(i=0;i<10000;i++)
ui->webView->page()->mainFrame()->findFirstElement("body").appendInside("<p>aaa</p>");
QMessageBox::information(NULL, "QWebElement::appendInside", QString("%1ms").arg(t.elapsed()));
}
void MainWindow::on_actionJavaScript_triggered()
{
//JavaScript版
QTime t;
t.start();
//断片をパースして追加するという意味ではdocumentFragmentを使って比較すべきかもしれない…。
ui->webView->page()->mainFrame()->evaluateJavaScript("var i;for(i=0;i<10000;i++){"
"var elm = document.createElement('p');"
"elm.appendChild(document.createTextNode('aaa'));"
"document.body.appendChild(elm);}");
QMessageBox::information(NULL, "QWebFrame::evaluateJavaScript", QString("%1ms").arg(t.elapsed()));
}
void MainWindow::on_actionTextBrowser_triggered()
{
//QTextBrowserとも比較してみる
int i;
QTime t;
t.start();
for(i=0;i<10000;i++){
ui->textBrowser->textCursor().movePosition(QTextCursor::End);
ui->textBrowser->insertHtml("<p>aaa</p><br>"); //brを入れないと処理がなぜか戻ってこない
}
QMessageBox::information(NULL, "QTextBrowser::insertHtml", QString("%1ms").arg(t.elapsed()));
}
結果は、C++でDOMをいじった場合400ms台、JavaScriptだと1500ms台、QTextBrowserは4000ms台でした(OS: Xubuntu 9.04 on VirtualBox, CPU: Core2Duo 1.6GHz)。QWebViewのC++とJSに関しては等価なコードではないので正確な比較ではありませんが… これなら2chブラウザをQtWebKitベースで作ってもあまり問題はなさそう(4.5のQWebViewはあからさまに遅かったのでQTextBrowserを使いました)。ただし、Qt 4.6ではイベント関連のAPIの整備が延期されているようなのが残念。QWebFrame::addToJavaScriptWindowObjectを駆使するしかないんかな?
なお、JavaScript版のコードを動かした後、ui->webView->page()->mainFrame()->findFirstElement("body").removeChildren();
とすると、なぜか一部の要素が残るという謎の結果が生じました。C++版だと起きず、完全にクリアされます。バグ?
Qt 4.6には、他にもJavaScriptCoreをバックエンドに選べるようになったQtScriptやQStateMachineなどおもしろげなものが転がってますので、一度さらっと眺めてみるといいかもしれません。