この質問はすでに答えられましたが、私は2セントで金を払うことができると思いました。
免責事項:私は数年間GeoDatabaseチームでESRIに勤務し、GeoDatabaseコードのさまざまな部分(バージョニング、カーソル、EditSessions、履歴、関係クラスなど)の管理を担当していました。
ESRIコードのパフォーマンスの問題の最大の原因は、さまざまなオブジェクト、特にさまざまなGeoDatabase抽象化の「小さな」詳細を使用することの意味を理解していないことです。非常に頻繁に、会話がパフォーマンスの問題の原因として使用されている言語に切り替わります。場合によっては可能です。しかし、常にではありません。言語の議論から始めましょう。
1.-選択するプログラミング言語は、複雑なことをタイトなループで行う場合にのみ重要です。ほとんどの場合、これは事実ではありません。
部屋の大きな象は、すべてのESRIコードの中核にArcObjectsがあり、ArcObjectsはCOMを使用してC ++で記述されていることです。このコードとの通信にはコストがかかります。これは、C#、VB.NET、Python、または使用している他のすべてのものに当てはまります。
そのコードの初期化時に料金を支払います。一度だけ実行する場合、それは無視できるほどのコストになります。
その後、ArcObjectsとやり取りするたびに料金を支払います。
個人的には、C#でクライアント用のコードを書く傾向があります。それは、それが十分に簡単で高速だからです。ただし、データを移動したり、ジオプロセシングで既に実装されている大量のデータの処理を行うたびに、スクリプトサブシステムを初期化し、パラメーターを渡します。どうして?
- すでに実装されています。では、なぜ車輪を再発明するのでしょうか?
- 実際にはもっと速いかもしれません。「C#で書くよりも速い?」はい!たとえば、データのロードを手動で実装すると、.NETコンテキストの切り替えのコストをタイトループで支払うことになります。すべてのGetValue、Insert、ShapeCopyにはコストがかかります。GPで1つの呼び出しを行うと、そのデータロードプロセス全体がGPの実際の実装(COM環境内のC ++)で発生します。コンテキスト切り替えがないので、私はコンテキスト切り替えの代価を払いません-したがって、それはより高速です。
ええ、そうです。それでは、多くのジオプロセシング関数を使用する場合の解決策です。実際、注意する必要があります。
2. GPは、データを(不必要に)コピーするブラックボックスです
それは両刃の剣です。内部で何らかの魔法をかけ、結果を吐き出すブラックボックスですが、これらの結果は非常に頻繁に複製されます。9つの異なる関数を使用してデータを実行した後、100,000行をディスク上の1,000,000行に簡単に変換できます。GP関数のみを使用することは、線形GPモデルを作成するようなものです。
3.大規模なデータセットに対して多すぎるGP機能をチェーン化することは非常に非効率的です。GPモデルは(潜在的に)本当に本当に馬鹿げた方法でクエリを実行することと同等です
誤解しないでください。私はGPモデルが大好きです-それはいつもコードを書くことから私を救います。しかし、大規模なデータセットを処理する最も効率的な方法ではないことも認識しています。
クエリプランナーについて聞いたことはありますか?実行するSQLステートメントを調べ、GPモデルのように見える有向グラフの形式で実行計画を生成し、dbに格納されている統計を見て、最も多く選択することです。それらを実行する最適な順序。GPは、あなたが物事を置く順番でそれらを実行するだけです。なぜなら、それはもっと賢く何かをする統計がないからです- あなたはクエリプランナーです。そして何だと思う?実行する順序は、データセットに大きく依存します。あなたが物事を実行する順序は、日と秒の違いを生む可能性があり、それはあなた次第です。
「素晴らしい」とあなたは言います、私は自分で物事をスクリプト化せず、私がものを書く方法に注意します。しかし、GeoDatabaseの抽象化は理解していますか?
4. GeoDatabaseの抽象化を理解していないと簡単に噛み付く
問題を引き起こす可能性のあるすべてのことを指摘する代わりに、私がいつも目にするいくつかのよくある間違いといくつかの推奨事項を指摘させてください。
- リサイクルカーソルのTrue / Falseの違いを理解する。この小さなフラグをtrueに設定すると、実行時の順序が大幅に速くなります。
- データをロードするには、テーブルをLoadOnlyModeに設定します。挿入ごとにインデックスを更新する理由
- IWorkspaceEdit :: StartEditingはすべてのワークスペースで同じように見えますが、それらはすべてのデータソースで非常に異なる獣であることを理解してください。エンタープライズGDBでは、トランザクションのバージョン管理またはサポートがあります。シェープファイルでは、非常に異なる方法で実装する必要があります。元に戻す/やり直しをどのように実装しますか?有効にする必要さえありますか(はい、メモリ使用量に違いが生じる可能性があります)。
- バッチ操作または単一行操作の違い。ポイントのケースGETROWS対GetRowをは -これは、1行を取得するクエリを実行するか、複数の行をフェッチするために、1つのクエリを実行するとの間の差です。GetRowの呼び出しでのタイトループはひどいパフォーマンスを意味し、パフォーマンスの問題の原因#1です
- UpdateSearchedRowsを使用する
- CreateRowとCreateRowBufferの違いを理解してください。挿入ランタイムの大きな違い。
- IRow :: StoreおよびIFeature :: Storeが非常に重い多態性操作をトリガーすることを理解してください。これがおそらく、パフォーマンスが本当に遅い2番目の原因です。行を保存するだけでなく、これはジオメトリックネットワークに問題がないこと、ArcMapエディターに行が変更されたことを通知する方法、この行に関係するすべてのリレーションシップクラスを検証する方法ですカーディナリティが有効であることなどを確認してください。これで新しい行を挿入しないでください。InsertCursorを使用する必要があります。
- EditSessionでこれらの挿入を行いますか(必要です)?それは作る巨大なあなたが行うかどう違いを。一部の操作ではそれが必要です(そして処理が遅くなります)が、必要ない場合は、元に戻す/やり直し機能をスキップしてください。
- カーソルは高価なリソースです。一度ハンドルを取得すると、一貫性と分離が保証され、コストがかかります。
- データベース接続(ワークスペース参照を作成および破棄しない)およびテーブルハンドル(1つを開いたり閉じたりするたびに-いくつかのメタデータテーブルを読み取る必要がある)などのその他のリソースをキャッシュします。
- FeatureClassをFeatureDatasetの内部または外部に配置すると、パフォーマンスに大きな違いが生じます。これは組織的な機能を意味するものではありません!
5.そして最後に重要なこと...
I / Oバウンド操作とCPUバウンド操作の違いを理解する
正直に言って、これらのアイテムのすべてをさらに拡張し、おそらくそれらのトピックのすべてをカバーする一連のブログエントリを実行することを考えましたが、私のカレンダーのバックログリストは私に顔を平手打ちして怒鳴り始めました。
私の2セント。