w3m 描画遅い問題

libbaygui の repaint を追ってみる。トップレベルウィンドウの repaint を呼ぶとコンポーネントの数 + 1 回の全描画要求が行くように見える。改善したいところだがここはボトルネックではないかもしれないので保留。

計測

遅そうな所に当たりをつけて MonAPI::Date::nowInMsec(); で計測。libbaygui Component.cpp の

  • c->getGraphics()->drawImage(this->_buffer, getX(), getY()); // 200msec
  • c->update(c->getX() + c->getInsets()->left + x, c->getY() + c->getInsets()->top + y, w, h); // 320 msec

ボトルネック

drawImage はこれ。

void Graphics::drawImage(Image* image, int x, int y)
{
    for (int i = 0; i < image->getHeight(); i++) {
        for (int j = 0; j < image->getWidth(); j++) {
            drawPixel(j + x, i + y, image->getPixel(j, i));
        }
     }
}

update の中では drawImage と GUI サーバーへの描画要求がありそれぞれ 160 msec 。

次の一手

drawImage は目的と構造が分かりやすい。チューニングの余地もありそう。
drawPixel と image->setPixel/getPixel が .cpp に定義されているのだけど、これらは inline 展開されて欲しいのでヘッダへ移動。
drawImage の速度が2倍になりこれだけで全体で 200 msec ほど速くなった。おお。見るからに速くなった。
とりあえずコミットしておく。


処理をよく見ると Image から Image へのメモリコピー。 Image の高さ回数分の memcpy で実装できそう。
実装したら drawImage は 20 msec になった。満足。

全描画を減らしたい

  void updatePane() {
    if(this->__g != NULL) {
//      repaint();
        m_pane->repaint();
    }

これではまずいかなあ。libbaygui に深く突っ込むのはまだ保留にしたいところ。今のところ十分速い。