经过一些重构,我设法将处理时间缩短到2.5分钟以下。权衡是在代码中部分构建了地理数据库架构,并在整理了所有关系后将对Arcgisscripting游标的请求限制为InsertCursors。
人们在处理大型数据集时使用了哪些技术来维持合理的计算时间?我错过了寻找优化的机会?我给人的印象是,表演并不是人们努力的最前沿。
作为ESRI产品的用户,有人期望并容忍这些性能落后吗?
UPDATE
使用此产品进行一些工作之后,我积累了一系列优化技术,这些技术已采取了将空间信息从适当格式转换为地理数据库的过程。这是为个人和文件地理数据库而开发的。
花絮:
读取数据并将其合理化在内存中。这将使您的时间减少一半。
在内存中创建要素类和表。使用要素数据集键盘功能'in_memory'将内存用作ram磁盘,在其中执行功能,然后写出到磁盘
要写出到磁盘,请对要素类使用CopyFeatureclass,对表使用CopyRow。 >
这3件事采用了一个脚本,该脚本将30万到30至40秒的100,000多个要素转换为地理数据库,其中包括关系类。请勿轻易使用它们,上面的大多数方法都占用大量内存,如果不注意,可能会导致问题。
#1 楼
尽管已经回答了这个问题,但我认为我可以给我2美分。游标,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进行数据加载。为什么要在每个插入上都更新索引?在企业GDB上,您可能具有版本控制或事务支持。在shapefile上,必须以非常不同的方式实现它。您将如何实施撤消/重做?您甚至需要启用它吗(是的,它可以在内存使用方面有所作为)。
批处理操作或单行操作之间的区别。例题GetRow与GetRows-这是执行查询以获取一行或执行查询以获取多行之间的区别。调用GetRow的紧密循环意味着糟糕的性能,这是性能问题的罪魁祸首#
使用UpdateSearchedRows
了解CreateRow和CreateRowBuffer之间的区别。插入运行时的巨大差异。
理解IRow :: Store和IFeature :: Store会触发超重的多态操作。这可能是导致性能真正下降的第二个原因。它不只是保存行,这是确保几何网络正常的方法,可确保ArcMap编辑器收到行已更改的通知,并通知与该行有任何关系的所有关系类进行验证确保基数有效,等等。您不应以此插入新行,而应使用InsertCursor!
是否要(需要)在EditSession中进行这些插入?不管您是否这样做,都会产生巨大的变化。某些操作需要它(并使其变慢),但是当您不需要它时,请跳过撤消/重做功能。
光标是昂贵的资源。一旦拥有一个句柄,就可以确保自己具有一致性和隔离性,并且要付出一定的代价。一次打开或关闭一个-需要读取几个元数据表。)
将FeatureClass放在FeatureDataset内部或外部会大大提高性能。
5.最后也是同样重要的...
了解I / O绑定和CPU绑定操作之间的区别
老实说,我想在其中的每个项目上进行更多的扩展,或者做一系列涵盖每个主题的博客文章,但是我日历的待办事项列表让我耳目一新,开始对我大喊大叫。 >我的两分钱。
评论
谢谢。我应该一直在做工作而不是写这篇文章哈哈
–拉吉·亚瑟(Ragi Yaser Burhum)
2011年4月28日在6:11
+1非常感谢您的宝贵意见Burhum先生。这是我希望收到的回应类型。如果我可以投票两次,我可以!尽管这些链接反映了ArcObjects和.Net概念,但是ArcGISScripting(python)用户应该从中得到的好处是,底层的COM对象是相同的,了解这些对象将有助于您更好地计划任何语言的代码。这里有很多很棒的信息!
–OptimizePrime
2011年4月29日在18:34
@OptimizePrime这是一个很棒的总结。而且您是对的-如果您想降低ESRI产品的性能,就不能忽略ArcObjects的含义。
–拉吉·亚瑟(Ragi Yaser Burhum)
11年4月29日在22:40
谢谢,我通过插入游标替换了store()并在我的应用程序中节省了大量时间!
–超级麻烦
2015年4月15日在13:42
#2 楼
通常,对于性能计算,我会尽量避免使用任何与ESRI相关的东西。对于您的示例,我建议分步进行此过程,第一步是将数据读取到普通的python对象中,然后进行计算,最后一步是转换为最终的ESRI空间格式。对于大约1万条记录,您可能会避免将所有内容存储在内存中进行处理,这将带来明显的性能提升。评论
感谢您的答复。这是一个很好的建议。在使用arcgisscripting之前,我已经开始重构代码以执行所需的过程。自从ArcInfo时代开始使用该软件后,我发现CPU性能和硬件功能的提高令人沮丧,ArcGIS Map / Info / Editor X.X性能停滞不前。也许引入GPU可能会推动事情发展。尽管良好地重构ESRI代码库也可能会有所帮助
–OptimizePrime
2011年4月6日的14:00
#3 楼
根据您拥有的硬件,您可能还考虑了ESRI Geocoder示例中显示的选项。它为您提供了一个分解大型数据集并运行多个python实例的框架,几乎为您提供了多线程方法。我看到地理编码的性能从单个Python实例中的每小时18万增加到超过一百万,这要归功于我的计算机上分解了8个并行进程。数据库中的数据工作,表中的功能工作以及仅在ESRI领域中使用显式GIS都会显着提高性能。评论
这些都是很棒的主意。我有机会在此脚本中线程一些进程,但是我发现瓶颈正在初始化COM库和Geodatabase I / O。关于I / O,我减少了一次写入的需要。如果我花更多的时间进行优化,那么我的老板会很合适;)因此,如果他要求更多,我将把线程作为性能的最后挤压。目前,我每分钟要处理60,000个功能。
–OptimizePrime
2011年4月29日在18:46
#4 楼
您可能会发现这些其他论坛帖子很有趣,因为它们在优化上下文中,但是对于栅格数据和整体而言:使用ArcGIS Geoprocessing Tools编译Python脚本?独立的Python脚本中的ArcGIS Hydrology工具箱工具与ArcCatalog相比?
您能否在原始问题中张贴一些代码示例,这些示例在UPDATE中演示数字1和2?我很想知道它的机制(尽管我假设您只在这里处理要素类数据)
,谢谢,
Tom
评论
您是否尝试过使用其他存储格式?文件地理数据库如何执行?文件地理数据库的性能略低于个人地理数据库。我昨天花费了很多时间来设置和调整ArcSDE实例,以测试企业格式的性能。我会通知你我的发现
现在这对您无济于事,但是在新版本的数据访问模块中,Python 10.1中的游标性能得到了很大的提高(平均情况下,幅度范围处于一定数量级)。
In_memory使用InMemoryWorkspaceedndoc.esri.com/arcobjects/9.2/ComponentHelp/esriDataSourcesGDB/…,在任意行后,将所有内容转储到ScratchWorkspaceFactory(即FileGDB)并依靠FileGDB来完成所有工作。 >