Curl Global Community
RecordGrid のパフォーマンスについて - Printable Version

+- Curl Global Community (https://communities.curl.com)
+-- Forum: Discussions (https://communities.curl.com/forumdisplay.php?fid=1)
+--- Forum: General Curl questions (https://communities.curl.com/forumdisplay.php?fid=2)
+--- Thread: RecordGrid のパフォーマンスについて (/showthread.php?tid=232)



RecordGrid のパフォーマンスについて - umemura - 08-24-2011

大量データを高速に表示できる RecordGrid ですが、
それでもカラムの数が膨大になってくると、スクロールや描画がモタつくことがありますよね。

とくにRecordGridCell などを継承して、RecordGridColumn のscell-spec に適用したカスタムセルを利用すると
その違いが顕著になるような気がしています。

少しでもパフォーマンスを上げたいときは、どんなことに気をつければいいのでしょうか。





RE: RecordGrid のパフォーマンスについて - umemura - 08-24-2011

もしそのセル(カラム)がIME入力を必要としないならば、
input-method-enabled? = false とすると、
矢印キーでのセル間のフォーカス移動がすばやくなるようです。

これは、セルが入力状態になるたびにIMEのON/OFFが切り替わっているのをスキップするためです。



RE: RecordGrid のパフォーマンスについて - umemura - 08-24-2011

RecordGrid のパフォーマンスは、主に各セル(カラム)の refresh-data メソッドの処理に依存するようです。
そのため、カスタムセルを利用する際、継承先のクラスでは、
なるべくこのメソッド内の処理を簡潔にすることがパフォーマンス向上の近道のようです。

また、データが存在せず、再描画しなくてもよいカラムなどがあれば、
refresh-data のなかで{supre.refresh-data} を呼ばないようにスキップすることで、
全体の描画速度が向上すると思います。

セルのプロパティにある possibly-displayed? を参照して下記のような記述をすると、
体感ですが、若干スクロールのスピードが上がったような気がしないでもなくもないです。

Code:
{if  self.possibly-displayed? == true then
        {super.refresh-data}
     else
        {after 0s do
            {if  self.possibly-displayed? == true then
                {super.refresh-data}
                
            }
        }
}



RE: RecordGrid のパフォーマンスについて - 森口 慶紀 - 09-02-2011

(08-24-2011, 04:23 PM)umemura Wrote: もしそのセル(カラム)がIME入力を必要としないならば、
input-method-enabled? = false とすると、
矢印キーでのセル間のフォーカス移動がすばやくなるようです。

これは、セルが入力状態になるたびにIMEのON/OFFが切り替わっているのをスキップするためです。
どうやらIMEツールバーによってフォーカス移動の速度が変わる様です。Sad
大量カラム、大量データを持たせたRecordGridにて速度の検証をしてみましたが、

Microsoft IME2003ではinput-method-enabled? = falseをしなくてもフォーカス移動の遅延はほとんどありませんでしたが、
Microsoft IME2007ではinput-method-enabled? = falseをしないとかなりフォーカス移動の遅延が見受けられました。
これはIMEツールバーの種類によって、IMEのON/OFF速度が異なるからなのでしょうかHuh




RE: RecordGrid のパフォーマンスについて - Yuhki - 09-05-2011

(08-24-2011, 04:23 PM)umemura Wrote: input-method-enabled? = false とすると、
矢印キーでのセル間のフォーカス移動がすばやくなるようです。
(09-02-2011, 07:18 PM)森口 慶紀 Wrote: どうやらIMEツールバーによってフォーカス移動の速度が変わる様です。
ちなみにセルの上下移動(↑or↓)のときに大きく影響がでるようですね。





RE: RecordGrid のパフォーマンスについて - Yuhki - 09-05-2011

(08-24-2011, 04:15 PM)umemura Wrote: 少しでもパフォーマンスを上げたいときは、どんなことに気をつければいいのでしょうか。
私は以下を気をつけます。
・設計段階でカラム数(表示している列数)を多くならないようにする
・継承したRecordGridCellクラスのrefresh-dataメソッドやformat処理に以下のような処理を書かない
 →Recordの値をセットする(RecordSetEventイベントが発生してしまうため)
 →Recordを検索する(RecordSet.selectなど)
・表示のみのカラムであればStandardFixedStringCell(またはそれを継承したクラス)を使用する

また思い出したら追記します。





RE: RecordGrid のパフォーマンスについて - fukuta - 09-08-2011

影響が大きい割によく忘れられがちなのは、プログラムからレコードの変更、追加、削除などを行うときに batch-events?=true を指定しないこと。これは痛い。

Code:
{with record-set.batch-events? = true do
    || レコードの変更、追加、削除など
}

厳密には、すでにRecordGridに関連づいているRecordSetに対して複数の変更(Recordに値をセットするとか、RecordGrid.appendするとか)を同時に行う場合に必須です。使いどきの判断が難しいと思う場合はなにも考えずに毎回これをかきましょう。イディオムです。



RE: RecordGrid のパフォーマンスについて - 森口 慶紀 - 09-09-2011

グリッドの表示領域が増えれば増えるほど、
画面に表示されるデータ(セル)が多くなる程、
描画に時間がかかる為、スクロールが遅くなってしまいますよね


Tongue



RE: RecordGrid のパフォーマンスについて - umemura - 01-06-2014

RecordGrid.batch-events?=true を指定するのとしないのとでは、かなりパフォーマンスに影響がありますね。

また、別スレッドの「セル単位での色指定」でも記載しましたが、
RecordGridCell.refresh-data の中で、このbatch-events?を参照するようにすると、
さらに全体のパフォーマンスが向上しました。


Code:
{curl 8.0 applet}
{curl-file-attributes character-encoding = "utf8"}
{applet manifest = "manifest.mcurl",
    {compiler-directives careful? = true}
}


{define-class public open CustomCell
  {inherits StandardStringCell }
  {constructor public {default}
    {construct-super}
  }

  {method public open {refresh-data}:void
    ||RecordSet.batch-events?=true の間は、
    ||再描画処理を行わない
    {if-non-null record = self.record,
        rs = self.record.record-set
    then
        {if not rs.batch-events? then
            {super.refresh-data}
            let (data:String, valid?:bool) = {self.get-formatted-data}
            {if {data.to-int} > 10  then
                set self.background = "pink"
             else
                {unset self.background}
            }
        }
    }
  }
}

{define-class public open CustomCell2
  {inherits StandardStringCell }
  {constructor public {default}
    {construct-super}
  }

  {method public open {refresh-data}:void
    {super.refresh-data}
    let (data:String, valid?:bool) = {self.get-formatted-data}
    {if {data.to-int} > 10  then
        set self.background = "pink"
    else
        {unset self.background}
    }
  }
}

{def rf-ary = {{Array-of RecordField}}}
{def col-ary = {{Array-of RecordGridColumn}}}
{def col-ary2 = {{Array-of RecordGridColumn}}}
{for i:int = 1 to 100 do
    def rf-name = "field-" & i
    {rf-ary.append {RecordField rf-name}}
    {col-ary.append {RecordGridColumn rf-name, cell-spec = CustomCell}}
    {col-ary2.append {RecordGridColumn rf-name, cell-spec = CustomCell2}}
}
{def rs = {RecordSet {RecordFields {splice rf-ary}}}}
{def rs2 = {RecordSet {RecordFields {splice rf-ary}}}}

{def grid =
    {RecordGrid
        height = 5in, width = 3in,
        record-source = rs
        , {splice col-ary}
    }
}
{def grid2 =
    {RecordGrid
        height = 5in, width = 3in,
        record-source = rs2
        , {splice col-ary2}
    }
}


||レコードの作成
{define-proc public {init-record rs:RecordSet}:void
    {rs.delete-all}
    {rs.commit}
    {for i:int = 0 to 5000 do
        def new-r = {rs.new-record}
        {for rf in rs.fields do
            set new-r[rf.name] = {String i}
        }
        {rs.append new-r}
    }
}

{CommandButton
    label = "クリア",
    {on Action do
        {rs.delete-all}
        {rs.commit}
        {rs2.delete-all}
        {rs2.commit}
    }
}

{HBox
    {VBox
        "refresh-data を ",
        "batch-event?=true 時にキャンセルする",
        {HBox

            {CommandButton
                label = "batch-events?あり",
                {on Action do
                    ||def dt = {DateTime}
                    {with rs.batch-events? = true do
                        {init-record rs}
                    }
                    ||{popup-message {dt.elapsed}}
                }
            },
            {CommandButton
                label = "batch-events?なし",
                {on Action do
                    ||def dt = {DateTime}
                    {init-record rs}
                    ||{popup-message {dt.elapsed}}
                }
            }
        },
        grid
    },
    {VBox
        "refresh-data を ",
        "常に処理する",
        {HBox
            {CommandButton
                label = "batch-events?あり",
                {on Action do
                    ||def dt = {DateTime}
                    {with rs.batch-events? = true do
                        {init-record rs2}
                    }
                    ||{popup-message {dt.elapsed}}
                }
            },
            {CommandButton
                label = "batch-events?なし",
                {on Action do
                    ||def dt = {DateTime}
                    {init-record rs2}
                    ||{popup-message {dt.elapsed}}
                }
            }
        }
        , grid2
    }
}