@GetDocField 関数を使って別の文書にあるフィールドの値を参照することがあります。
次のような感じです。
@GetDocField( UNID; "Subject" );
UNID には親文書の UNID がテキスト形式でセットされていたりします。
主要な値は親文書に保持しておき、子文書・孫文書には値を持たずに @GetDocField を使って親文書を参照する。こうすることで、主要な値を変えたい場合は親文書だけ変更すればよく、子文書・孫文書を変更する必要がなくなります。
ずいぶん前ですが @GetDocField を「使い過ぎちゃいます?」と言いたくなるほど多く使っているフォームがありました。少なくとも 50 のフィールドで使っていたと記憶しています。
リモートのアプリに対してアクセスする場合は @GetDocField は新たな NRPC コマンドを発行するんだろうなと想像できますが、このフォームでは何度も同じ文書を参照していたこともあって、次のどちらになるのか気になりました。
・NRPC コマンドは最初の1度だけ発行される?
・それともコマンドの数だけ発行される?
そこで notes.ini へ次の3行を設定して NRPC コマンドの記録を取って確認してみることにしました。
CLIENT_CLOCK=1
CONSOLE_LOG_ENABLED=1
DEBUG_THREADID=1
※Notes クライアントは 12.0.1 、Domino は 12.0.1 または 12.0 を使用してます。
まずは、1つの @GetDocField を式に設定したフィールドが1つだけあるフォームを開いてみました。すると console.log に次の1行が記録されました。
[7C8C:0002-5DB8] (5956-5335 [6435]) OPEN_NOTE_UNIDNAME_RQST(REP492587B3:0040D090-UNIDED7FB824:844179CF-492587B3:004126DE,03400000): 0 ms. [82+2546=2628]
OPEN_NOTE_UNIDNAME_RQST というNRPC コマンドが親文書の UNID を参照しています。時間は 1 ミリ秒より小さく、送信 82 バイト + 受信 2546 バイトであったことを示しています。なお、この環境は Notes クライアントと同じPC内で Domino サーバーが稼働しています。そのため時間は無視できるほど小さくなりました。
ところで Notes では、@DbLookup 関数は "Cache" というパラメータがあったり、一度読み込んだ文書(設計要素)をキャッシュして 2 度目以降は素早く開いたりと、キャッシュを上手に使うイメージがあります。
そこで、@GetDocField を同じ UNID に対して何度もコールすると 2 度目以降はどうなるか見ていきます。
@GetDocField を使用したフィールドをフォーム内に 4 つコピーして、合計 5 つのフィールドで同じ式を指定している状態にします。ここで期待するのは、1 度目の NRPC コマンド発行の後(クライアント側にキャッシュされたものを参照するため)2 度目の NRPC コマンドを発行しないことです。
このフォームで文書を開いてみたところ console.log には同じ UNID の文書を 5 回読み込んだことを示す、次の 5 行が記録されました。
[7C8C:0002-5DB8] (6950-6299 [7526]) OPEN_NOTE_UNIDNAME_RQST(REP492587B3:0040D090-UNIDED7FB824:844179CF-492587B3:004126DE,03400000): 1 ms. [82+2546=2628]
[7C8C:0002-5DB8] (6951-6299 [7527]) OPEN_NOTE_UNIDNAME_RQST(REP492587B3:0040D090-UNIDED7FB824:844179CF-492587B3:004126DE,03400000): 0 ms. [82+2546=2628]
[7C8C:0002-5DB8] (6952-6299 [7528]) OPEN_NOTE_UNIDNAME_RQST(REP492587B3:0040D090-UNIDED7FB824:844179CF-492587B3:004126DE,03400000): 1 ms. [82+2546=2628]
[7C8C:0002-5DB8] (6953-6299 [7529]) OPEN_NOTE_UNIDNAME_RQST(REP492587B3:0040D090-UNIDED7FB824:844179CF-492587B3:004126DE,03400000): 1 ms. [82+2546=2628]
[7C8C:0002-5DB8] (6954-6299 [7530]) OPEN_NOTE_UNIDNAME_RQST(REP492587B3:0040D090-UNIDED7FB824:844179CF-492587B3:004126DE,03400000): 1 ms. [82+2546=2628]
NRPC コマンドは、5 つのフィールドの式が同じ文書(かつ同じフィールド)を参照しているにも関わらず 5 回発行されることがわかりました。時間はほぼ同じで、送信と受信のバイト数も同じです。
次に、さきほどの
「5 つのフィールドに @GetDocField を 1 つずつ」を
「1 つのフィールドに @GetDocField を 5 つ」
に変更してみます。元からあるフィールドの式を次のように変更して、さきほど追加した 4 つのフィールドは削除します。
@GetDocField( UNID; "Subject" ) + @GetDocField( UNID; "Subject" ) + @GetDocField( UNID; "Subject" ) + @GetDocField( UNID; "Subject" ) + @GetDocField( UNID; "Subject" )
参照先の文書もフィールド名も同じ関数が 5 つあるという意味では、直前の実験と同じです。しかしながらこのフォームで文書を開いてみると、console.log には NRPC コマンドが 1 行しか記録されなかったのです。
[7C8C:0002-5DB8] (7343-6689 [8006]) OPEN_NOTE_UNIDNAME_RQST(REP492587B3:0040D090-UNIDED7FB824:844179CF-492587B3:004126DE,03400000): 1 ms. [82+2546=2628]
では、同じ文書にある別のフィールドを参照してみるとどうなるのでしょうか。
さきほどの式を少し書き換えて親文書にある 2 つのフィールド("Subject"と"Form")を参照させます。
@GetDocField( UNID; "Subject" ) + @GetDocField( UNID; "Form" ) + @GetDocField( UNID; "Subject" ) + @GetDocField( UNID; "Form" ) + @GetDocField( UNID; "Subject" )
このフォームで開いてみても、NRPC コマンドは 1 回発行されただけでした。
[7C8C:0002-5DB8] (8983-9032 [9719]) OPEN_NOTE_UNIDNAME_RQST(REP492587B3:0040D090-UNIDED7FB824:844179CF-492587B3:004126DE,03400000): 1 ms. [82+2546=2628]
異なるフィールドを参照してみましたが、受信のサイズは 1 つのフィールドの時と同じ 2546 バイトになりました。
受信のサイズが、参照するフィールド名に依存しないことを確かめるため、@GetDocField で参照している親文書へ 32,000 バイトの値を持つアイテムを新たに追加してみて、受信のサイズが変わるのかどうか試してみました。式の内容は変更せず、追加した 32,000 バイトのフィールド名は @GetDocField で指定していません。
[2C78:0002-C228] (1162-1114 [1255]) OPEN_NOTE_UNIDNAME_RQST(REP492587B3:0040D090-UNIDED7FB824:844179CF-492587B3:004126DE,03400000): 0 ms. [82+34684=34766]
検証の結果をまとめます。
- @GetDocField を使用するフィールドが多数あると、NRPC コマンドはフィールドの数だけ発行された。
- 1 つのフィールド内に複数の @GetDocField をまとめて使用すると、NRPC コマンドは1度だけ発行された。
- @GetDocField で受信するデータのサイズは、指定するフィールドによらず同じだった。
- 同一文書を参照する場合の NRPC コマンドの時間は、初回のコールでDomino側に文書がキャッシュされたため、2 回目以降のコールでは短縮された。
これらを踏まえると、同一文書を参照する @GetDocField を多数使いたい場合、なるべく 1 つのフィールド内でまとめて使うことが良い、と言えます。
下のサンプルでは「temp」というフィールドの式で@GetDocField で参照した値を別のフィールドへセットすることを繰り返し行っています。
このサンプルでは「temp」フィールドの式で @GetDocField を 61 回使用していますが、実行してみたところ NRPC コマンドの発行は 1 度だけでした。NRPC コマンドの発行回数が抑えられたことで、フォームを開く際のパフォーマンスを改善できました。
※あくまで @GetDocField を使うことにこだわった改善例ですが、改善の方法は他にもありそうです
以上の結果を踏まえ、仕様面での改善依頼をアイデアポータルへ投稿しました。
@GetDocField は、「のの会」の話題にもありましたが、一つの使い方の例は、@Picklist([CUSTOM]) 関数から戻すカラムの値を文書の UNID にしておき、その UNID を @GetDocField に指定することで、@Picklist で選択した文書にある複数のフィールド値にアクセスすることができる、というものでした。
この話題がのの会で上がっている時、過去に気になっていたものが何なのか思い出せなくて実はモヤモヤしていたのですが、先日同様のフォームを見かけてようやく思い出すことができました。
それから今回の検証で久しぶりに体感したことがありました。それは NRPC コマンドの時間ですが、Notes クライアントと同じ PC 内に構築した Domino サーバーへのアクセスでは初回も 2 回目以降も同じ 1 ms程度の値を示していました。ところがアプリケーションをクラウド上にある Domino サーバーへ移設した後、ビューでダブルクリックして文書が開くまでの時間が明らかに遅くなったのです。このときの NRPC コマンドの記録が上で示したスクリーンショットですが、@GetDocField を使うフィールドが 61 個あるフォームを開くのに 20 秒弱でした。移設前はサクッと開いていたのですが、速いネットワークにすっかり慣れてしまっていたせいか、今後 HCL Nomad などで多用されると思われるインターネット越しの Domino へのアクセスでここまで遅くなった事実に愕然としました。
@GetDocField を使ったフィールドが多数あるフォームを含むアプリケーションを、狭帯域だったり遅延の大きいネットワーク越しにある Domino サーバーに置く場合も想定して開発しなきゃならないなと思いました。
0 件のコメント:
コメントを投稿