GrapeCity.devlog

グレープシティ株式会社のDeveloper Tools〈開発支援ツール〉の、製品のTIPSや発売などに関する最新情報をお届けします。

GrapeCity

SPREAD高速化テクニック!(1) 描画処理の高速化

こんにちは。今日は弊社製品「SPREAD(スプレッド)」シリーズをお使いのお客様に向け、動作時のパフォーマンス向上に寄与する小技をご紹介したいと思います。なお、小技と言いましたが難しい設定はひとつもありません。少しのコード変更で開発中のアプリケーションを高速化できる可能性があり、もしかしたらプログラミングの総量も減るかもしれませんので、ぜひお試しください。

速くしたい!大規模な描画処理

SPREADシリーズは、20年以上にわたり多くのお客様からご利用いただいている弊社の代表製品です。Windows Forms、ASP.NET、WPF、JavaScriptなどを使った開発で、アプリケーションにExcelライクなスプレッドシートを簡単に組み込むことのできる大変便利なコンポーネント製品となっています。

Excelライクな画面を実現できるSPREADシリーズ

〜 Excelライクな画面を実現できるSPREADシリーズ 〜

そんな同シリーズで、過去から現在にわたりプラットフォームを問わず頻繁にいただくお問い合わせ、それが「描画処理を速くしたい!」です。具体的には、以下のような処理でパフォーマンスの問題に直面されることが多いようです。

  • シート上のセルすべてに同じ背景色を設定する
  • 特定行にあるセルすべてのフォントを変更する
  • 特定列のセルすべてに同種のセル型を設定する

このような処理でパフォーマンスの問題が発生している場合に詳しくお話をお伺いすると、ほとんどのケースで皆さま、対象の各セルにループ処理で設定を行う、というやり方を採用されています。ここがポイントです。

SPREADに対して実施できる設定の単位はセルのみにあらず!製品の備えるAPIとその処理単位を正しく把握することで、このようなケースでのパフォーマンス向上が期待できます。

シート、行、列、セル単位の処理

今回ご紹介する小技のコンセプトと要点は、Microsoft Excelでの操作を想像すると分かりやすいかもしれません。Excelでシート全体や行全体、列全体に何かをしたいとき、シートコーナーや見出し行(もしくは見出し列)をクリックしてから、その選択範囲に対して設定を行いますよね?SPREADでも、コード処理で同じようなことができます。

SPREADの処理単位

〜 SPREADの処理単位 〜

前述した各セルへの設定とその描画速度も、SPREADが備えるシート単位や行列単位で処理するAPIで高速になる可能性があります。

やっていることは同じでは?

このようなご案内をすると、お客様からは以下のようなご質問をいただきます。

Q.シート単位や行例単位で処理するAPIを使っても、SPREAD内部では特定のセル範囲に対して結局ループ処理をすると思うので、結果は同じではないですか?

たしかにSPREAD内部でも特定のセル範囲に対してループ処理を行いますが、セル単位で処理する製品の公開APIをそのままコールして処理を実施するわけではありません。設定結果を得るのにあたり内部用に最適化した方法で処理が実施されるので、シート単位や行例単位で処理するAPIのパフォーマンスは、前述の各セルを対象としたループ処理よりも高速です。

実演

今回はSpreadJSのケースを例にとり、行単位とセル単位のAPI処理のパフォーマンス差を見てみたいと思います。SpreadJSの場合はgetCellメソッドを使い、その引数で処理範囲を指定することでセル単位の処理と行単位の処理をそれぞれ実行することが可能です。以下に例を示します。

セル単位の処理を行う場合の例

// セルを取得します
var cell = sheet.getCell(0,0);
// セルに対して処理を実行します(セルの背景色を赤に設定)
cell.backColor("red");

行単位の処理を行う場合の例

// 行を取得します
// 列インデックスを指定する第二引数に
// "-1"を設定することで行全体を取得できます)
var row = sheet.getCell(0,-1);
// 行に対して処理を実行します(行の背景色を赤に設定)
row.backColor("red");

次のデモでは、15万列あるスプレッドシートを用意しました。つまり、1つの行に15万セルです。ある行全体の背景色を変更する場合、セルごとと行単位の処理とではどちらのやり方が高速でしょうか。以下のデモでそれぞれの処理を実行するボタンを押下し、確認してみてください。

弊社環境においてGoogle Chrome上で4回程度、それぞれの処理を実行した場合の平均処理速度は

セル単位の処理3.5秒〜4秒
行単位の処理0秒(時々1ミリ秒)※速すぎて計測不可となることがほとんどでした。

となりました。処理方法の違いによって歴然としたパフォーマンス差が生まれてくることがご理解いただけたかと思います。

上手な使い方でパフォーマンス向上

今回ご覧いただいたように、製品のAPIを上手に正しく使用することでSPREADを使ったアプリケーションをより高速にできる可能性がグッとアップします。現在ご開発中のアプリケーションで心あたりがあればぜひ、お試しください。なお、各プラットフォーム版のSPREADにおけるシート、行、列、セル単位の処理方法はそれぞれ、製品ヘルプにある以下の項目で確認できます。

SPREAD for Windows Forms

SPREAD for ASP.NET

SPREAD for WPF

SpreadJS(Spread.Sheetsライブラリ)

  • getCellメソッド、やgetRangeメソッドを使い、引数で任意のセル座標やセル範囲を指定することで、シート、行、列、セル単位のデータ設定と取得ができます。
  • 初期化などにおけるシート全体へのスタイル処理では、デフォルトスタイルが利用できます。
  • グレープシティ株式会社のDeveloper Tools〈開発支援ツール〉ではエンジニア経験者を幅広く募集しています。
  • グレープシティ株式会社のDeveloper Tools〈開発支援ツール〉の製品のデモアプリケーションをお試しください。