尽管已经回答了这个问题,但我认为我可以给我2美分。
免责声明:我在GeoDatabase团队的ESRI工作了几年,负责维护GeoDatabase代码的各个部分(版本,游标,EditSession,历史记录,关系类等)。
我认为ESRI代码的性能问题的最大根源不是不了解使用不同对象的含义,尤其是各种GeoDatabase抽象的“小”细节!因此,通常情况下,对话会切换为导致性能问题的原因的语言。在某些情况下可以。但并非一直如此。让我们从语言讨论开始,然后再往回走。
1.-您选择的编程语言仅在执行复杂且紧密循环的事情时才有意义。在大多数情况下,情况并非如此。
房间里最大的麻烦是,在所有ESRI代码的核心处,都有ArcObjects-并且ArcObjects是使用COM用C ++编写的。与该代码进行通信需要一定的费用。对于C#,VB.NET,python或您正在使用的其他任何工具都是如此。
您需要在初始化该代码时付出代价。如果只进行一次,则成本可以忽略不计。
然后,您需要为以后每次与ArcObjects进行交互付出的代价。
就个人而言,我倾向于使用C#为客户编写代码,因为它既简单又快速。但是,每次我要移动数据或对地理处理中已经实现的大量数据进行一些处理时,我都只是初始化脚本子系统并传递参数。为什么?
- 它已经实现。那么,为什么要重新发明轮子呢?
- 实际上可能更快。“比用C#编写还快?” 是! 例如,如果我手动实现数据加载,则意味着我要付出紧密循环中的.NET上下文切换的代价。每个GetValue,Insert,ShapeCopy都有成本。如果我在GP中进行一次调用,则整个数据加载过程将在GP的实际实现中进行-在COM环境中以C ++进行。我不为上下文切换付出任何代价,因为它不存在-因此速度更快。
嗯,是的,因此解决方案是否要使用很多地理处理功能。实际上,您必须要小心。
2. GP是一个黑匣子,可在周围复制数据(可能不必要)
这是一把双刃剑。这是一个黑匣子,内部会做一些魔术,并吐出结果-但是这些结果通常是重复的。通过9种不同的功能运行数据后,可以轻松地将100,000行转换为磁盘上的1,000,000行。仅使用GP函数就像创建线性GP模型一样,而且...
3.对于大型数据集,链接太多的GP函数效率很低。GP模型(潜在地)等效于以一种非常愚蠢的方式执行查询
现在不要误会我的意思。我喜欢GP模型-它使我免于一直编写代码。但我也知道,这不是处理大型数据集的最有效方法。
大家都听说过查询计划器吗?工作是查看要执行的SQL语句,以有向图的形式生成执行计划,该执行图看起来很像GP模型,查看存储在数据库中的统计信息,然后选择最执行它们的最佳顺序。GP只是按照您放东西的顺序执行它们,因为它没有统计信息可以更智能地执行任何操作- 您是查询计划者。你猜怎么着?执行事情的顺序非常取决于数据集。您执行事情的顺序可以使天和秒有所不同,这取决于您自己决定。
你说“好”,我不会自己编写脚本,并且要小心写东西。但是您了解GeoDatabase抽象吗?
4,不了解GeoDatabase抽象会轻易咬你
我没有指出可能会给您带来问题的每件事,而是让我指出了我经常看到的一些常见错误和一些建议。
- 了解回收游标的True与False之间的区别。将此小标志设置为true可以使运行时快几个数量级。
- 将表置于LoadOnlyMode进行数据加载。为什么要在每次插入时更新索引?
- 可以理解,即使IWorkspaceEdit :: StartEditing在所有工作空间中看起来都一样,但它们在每个数据源上都是非常不同的野兽。在企业GDB上,您可能具有版本控制或事务支持。在shapefile上,必须以非常不同的方式来实现它。您将如何实施撤消/重做?您甚至需要启用它吗(是的,它可以在内存使用方面有所作为)。
- 批处理操作或单行操作之间的区别。以GetRow与GetRows为例 -这是执行查询以获取一行或执行查询以获取多行之间的区别。调用GetRow的紧密循环意味着糟糕的性能,这是性能问题的元凶#1
- 使用UpdateSearchedRows
- 了解CreateRow和CreateRowBuffer之间的区别。插入运行时的巨大差异。
- 了解IRow :: Store和IFeature :: Store会触发超重的多态操作。这可能是导致性能真正下降的第二个原因。它不只是保存行,这是确保几何网络正常的方法,可确保ArcMap编辑器收到行已更改的通知,并通知与该行有任何关系的所有关系类进行验证确保基数有效,等等。您不应以此插入新行,而应使用InsertCursor!
- 您是否要(需要)在EditSession中进行这些插入?不管您是否这样做,都会产生巨大的变化。某些操作需要它(并使其变慢),但是当您不需要它时,请跳过撤消/重做功能。
- 游标是昂贵的资源。一旦处理了一个问题,就可以确保自己具有一致性和隔离性,并且要付出代价。
- 缓存其他资源,例如数据库连接(不要创建和销毁Workspace引用)和表句柄(每次打开或关闭一个资源-都需要读取几个元数据表)。
- 将FeatureClass类放在FeatureDataset的内部或外部会对性能产生巨大的影响。这并不是组织功能!
5,最后同样重要的是...
了解I / O绑定和CPU绑定操作之间的区别
老实说,我想在这些项目的每一个上进行更多的扩展,或者做一系列涵盖每个主题的博客条目,但是我日历的待办事项列表只是打了我一脸,就开始对我大吼大叫。
我的两分钱。