ArcGISScripting 및 대규모 공간 데이터 세트의 성능


38

현재 arcgisscripting 모듈을 사용하여 소수의 테이블 (총 8 개)에 대해 표준화 된 합리적으로 큰 데이터 세트 (총 10,000 레코드)를 처리하는 Python 스크립트를 작성하고 있습니다. 이 프로세스는 좌표 튜플 (x, y)을 기반으로 형상을 생성하고 다른 7 개 표의 관계를 사용하여 그래프 (노드 및 선)를 생성하여 안내합니다. 최종 결과물은 관계를 시각적으로 나타내는 노드 및 엣지 공간 데이터 세트가있는 개인 지오 데이터베이스 (pgdb / fgdb)입니다.

초기 시도는 새로운 지오 데이터베이스 테이블과 SearchCursor 레코드 세트의 쿼리를 사용하여 발생하는 다 대다 관계에 대한 링크 테이블 (InsertCursor)을 채우는 것입니다. 이것은 15-20 분의 처리 시간을 제외하고는 매우 잘 작동했습니다.

Python에서 cProfiler 모듈을 사용하면 검색 쿼리를 수행 할 때 커서 (검색 및 삽입 커서)에 대한 요청으로 링크 테이블을 채울 때 개인 지오 데이터베이스를 '쓰 레싱'하는 것이 끔찍한 성능을 유발했습니다.

약간의 리팩토링으로 처리 시간을 2.5 분 미만으로 유지할 수있었습니다. 트레이드 오프는 코드에서 지오 데이터베이스 스키마를 부분적으로 구성한 것으로 모든 관계가 조합 된 후 원호 스크립팅 커서에 대한 요청을 InsertCursors로 제한했습니다.

내 질문은 성능 중 하나입니다.

  • 대규모 데이터 세트로 작업 할 때 합리적인 계산 시간을 유지하기 위해 사람들이 사용한 기술은 무엇입니까?
  • 최적화 검색에서 놓친 ESRI 권장 방법이 있습니까?

    특히 개인용 지오 데이터베이스를 사용하는 경우 원고 스크립팅 커서를 만들 때 발생하는 오버 헤드를 이해합니다.이 사이트와 Google에서 성능 관련 답변을 오랫동안 검색 한 후에는 사람들의 노력이 퍼포먼스에 미치지 못한다는 인상을 받았습니다. .

  • ESRI 제품의 사용자로서 이러한 성능 지연을 예상하고 수용합니까?

최신 정보

이 제품으로 작업 한 후 공간 정보를 적절한 형식에서 지리 데이터베이스로 변환하는 프로세스를 수행 한 최적화 기술 목록을 쌓았습니다. 개인 및 파일 지오 데이터베이스 용으로 개발되었습니다. 가벼운 음식 :

  1. 데이터를 읽고 메모리에 합리화하십시오. 시간이 반으로 줄어 듭니다.

  2. 메모리에 피쳐 클래스 및 테이블을 작성하십시오. 기능 데이터 세트 키 워크 'in_memory'를 사용하여 메모리를 램 디스크로 사용하고 기능을 수행 한 다음 디스크에 씁니다.

  3. 디스크에 쓰려면 기능 클래스에 CopyFeature 클래스를 사용하고 테이블에 CopyRow를 사용하십시오.

이 3 가지 작업에는 100,000 개 이상의 기능을 30 분에서 30-40 초로 지오 데이터베이스로 변환하는 스크립트가 필요했으며 여기에는 관계 클래스가 포함됩니다. 그것들은 가볍게 사용되지 않아야합니다. 위의 대부분의 방법은 많은 메모리를 사용하므로주의를 기울이지 않으면 문제가 발생할 수 있습니다.


1
다른 저장소 형식을 사용해 보셨습니까? 파일 지오 데이터베이스는 어떻게 수행됩니까?
Derek Swingley

파일 지오 데이터베이스는 개인 지오 데이터베이스보다 약간 나쁩니다. 어제 엔터프라이즈 형식의 성능을 테스트하기 위해 ArcSDE 인스턴스를 설정하고 조정하는 데 보냈습니다. 내가
OptimizePrime

2
이것은 지금 당신에게 도움이되지 않지만 10.1에서는 새로운 데이터 액세스 모듈을 사용하여 파이썬의 커서 성능이 큰 요인 (평균 사례의 크기 범위의 순서)으로 향상되었습니다.
Jason Scheirer

In_memory는 InMemoryWorkspace edndoc.esri.com/arcobjects/9.2/ComponentHelp/esriDataSourcesGDB/… 를 사용합니다. 이 행은 임의의 수의 행 후에 모든 것을 ScratchWorkspaceFactory (예 : FileGDB)에 덤프하고 FileGDB에 의존하여 모든 작업을 수행합니다
Ragi Yaser Burhum

답변:


56

이 질문에 이미 대답했지만, 나는 2 센트를주고 차임 할 수 있다고 생각했다.

면책 조항 : 몇 년 동안 GeoDatabase 팀에서 ESRI에서 근무했으며 GeoDatabase 코드의 다양한 부분 (버전 관리, 커서, 편집 세션, 기록, 관계 클래스 등)을 담당했습니다.

ESRI 코드의 성능 문제의 가장 큰 원인은 다양한 객체 사용, 특히 다양한 GeoDatabase 추상화의 "작은"세부 사항 사용의 의미를 이해하지 못하는 것입니다! 종종 대화가 성능 문제의 원인으로 사용되는 언어로 전환됩니다. 어떤 경우에는 가능합니다. 그러나 항상 그런 것은 아닙니다. 언어 토론부터 시작해 보도록하겠습니다.

1. 선택한 프로그래밍 언어는 복잡한 루프에서 복잡한 작업을 수행 할 때만 중요합니다. 대부분의 경우, 그렇지 않습니다.

방의 큰 코끼리는 모든 ESRI 코드의 핵심에는 ArcObjects가 있으며 ArcObjects는 COM을 사용하여 C ++로 작성 된다는 것 입니다. 이 코드와의 통신 비용이 있습니다. 이것은 C #, VB.NET, python 또는 기타 사용하는 모든 경우에 해당됩니다.

해당 코드를 초기화 할 때 가격을 지불합니다. 한 번만하면 비용이 무시할 수 있습니다.

그런 다음 ArcObject와 상호 작용할 때마다 이후에 요금을 지불합니다.

개인적으로 C #에서는 클라이언트를위한 코드를 작성하는 것이 쉽고 빠르기 때문에 C #으로 작성하는 경향이 있습니다. 그러나 지리 처리에서 이미 구현 된 대량의 데이터 처리하거나 처리 할 때마다 스크립팅 하위 시스템을 초기화하고 매개 변수를 전달합니다. 왜?

  • 이미 구현되었습니다. 그렇다면 왜 바퀴를 재발 명합니까?
  • 실제로 더 빠를 수 있습니다 . "C #으로 작성하는 것보다 더 빨리?" 예! 예를 들어 수동으로 데이터로드를 구현하면 .NET 컨텍스트 전환 비용을 빡빡한 루프로 지불한다는 의미입니다. 모든 GetValue, Insert, ShapeCopy에는 비용이 있습니다. GP에서 한 번 호출하면 전체 데이터로드 프로세스가 COM 환경 내 C ++의 실제 GP 구현에서 발생합니다. 컨텍스트 전환 비용이 없기 때문에 더 빠릅니다.

예, 그렇다면 지리 처리 기능을 많이 사용하는 경우 해결책입니다. 실제로 조심해야합니다.

2. GP는 데이터를 잠재적으로 불필요하게 복사하는 블랙 박스입니다.

양날의 칼입니다. 내부적으로 일부 마법을 수행하고 결과를 내뿜는 블랙 박스이지만 이러한 결과는 종종 복제됩니다. 9 개의 다른 기능을 통해 데이터를 실행 한 후 디스크에서 100,000 개의 행을 1,000,000 개의 행으로 쉽게 변환 할 수 있습니다. GP 함수 만 사용하는 것은 선형 GP 모델을 만드는 것과 같습니다.

3. 큰 데이터 세트에 너무 많은 GP 기능을 연결하는 것은 매우 비효율적입니다. GP 모델은 (실제적으로) 실제로 정말 바보 같은 방식으로 쿼리를 실행하는 것과 같습니다.

이제 내가 틀리지 마 나는 GP Models를 좋아합니다-항상 코드를 작성하는 것을 막아줍니다. 그러나 나는 그것이 큰 데이터 세트를 처리하는 가장 효율적인 방법이 아니라는 것을 알고 있습니다.

Query Planner에 대해 들어 본 적이 있습니까? 작업은 실행하려는 SQL 문을보고 GP Model 과 비슷한 모양의 직접 그래프 형태로 실행 계획을 생성 하고 db에 저장된 통계를보고 가장 많은 것을 선택하는 것입니다. 그들을 실행하는 최적의 순서 . GP는보다 지능적인 작업을 수행 할 통계가 없으므로 쿼리 플래너 입니다. 그리고 무엇을 추측합니까? 작업을 수행하는 순서는 데이터 세트에 따라 다릅니다. 일을 실행하는 순서는 일과 초의 차이를 만들 수 있으며 결정하는 것은 당신에게 달려 있습니다.

"좋아요"라고 말하면, 나는 스스로 물건을 스크립팅하지 않고 물건을 쓰는 방법에주의해야합니다. 그러나 GeoDatabase 추상화를 이해합니까?

4. GeoDatabase 추상화를 이해하지 못하면 쉽게 물릴 수 있습니다.

문제를 일으킬 수있는 모든 것을 지적하는 대신 항상 볼 수있는 몇 가지 일반적인 실수와 몇 가지 권장 사항을 지적하겠습니다.

  • 재활용 커서에 대한 참 / 거짓 의 차이점 이해 . 이 작은 작은 플래그가 true로 설정되면 런타임 크기가 더 빨라질 수 있습니다.
  • 데이터로드를 위해 테이블을 LoadOnlyMode 에 두십시오 . 모든 삽입물에서 색인을 업데이트해야하는 이유는 무엇입니까?
  • IWorkspaceEdit :: StartEditing이 모든 작업 공간에서 동일하게 보이지만 모든 데이터 소스에서 매우 다른 짐승임을 이해하십시오. Enterprise GDB에서 버전 관리 또는 트랜잭션 지원이있을 수 있습니다. 쉐이프 파일에서는 매우 다른 방식으로 구현되어야합니다. Undo / Redo를 어떻게 구현 하시겠습니까? 활성화해야합니까 (예, 메모리 사용량에 차이가있을 수 있습니다).
  • 일괄 작업 또는 단일 행 작업의 차이점 포인트 GetRow 대 GetRows- 한 행을 얻기 위해 쿼리를 수행하거나 여러 행을 가져 오기 위해 하나의 쿼리를 수행하는 것의 차이점입니다. GetRow를 호출하는 긴밀한 루프는 끔찍한 성능을 의미하며 성능 문제의 주요 원인입니다.
  • UpdateSearchedRows 사용
  • CreateRowCreateRowBuffer 의 차이점을 이해하십시오 . 삽입 런타임에 차이가 있습니다.
  • IRow :: Store 및 IFeature :: Store는 매우 무거운 다형성 작업을 트리거 한다는 것을 이해하십시오 . 이것이 아마도 성능 저하의 원인 인 # 2 원인 일 수 있습니다. 행을 저장하는 것이 아니라 기하학적 네트워크가 올바른지 확인하고 ArcMap Editor가 행이 변경되었다는 알림을 받고이 행과 관련이있는 모든 관계 클래스에 알립니다. 카디널리티가 유효한지 확인하십시오. 이와 함께 새 행을 삽입해서는 안되며 InsertCursor 를 사용해야합니다 !
  • EditSession에서 해당 삽입을 수행해야합니까? 당신이하지 않으면 차이를 만듭니다 . 일부 작업에는 필요하고 속도가 느리지 만 필요하지 않은 경우 실행 취소 / 다시 실행 기능을 건너 뜁니다.
  • 커서는 값 비싼 리소스입니다. 하나를 처리하면 일관성과 격리 가 보장 되며 비용이 발생합니다.
  • 데이터베이스 연결 (작업 공간 참조를 작성 및 파괴하지 않음) 및 테이블 핸들 (하나를 열거 나 닫을 때마다 여러 메타 데이터 테이블을 읽어야 함)과 같은 다른 자원을 캐시하십시오.
  • FeatureDataset 내부 또는 외부에 FeatureClass를 배치하면 성능이 크게 달라집니다. 조직적인 기능 이 아닙니다 !

5. 그리고 마지막으로 ...

I / O 바운드와 CPU 바운드 작업 의 차이점 이해

나는 솔직히 그 아이템들 각각에 대해 더 많은 것을 확장하고 아마도 그 주제들 각각을 다루는 일련의 블로그 항목을 수행하는 것에 대해 생각했지만 내 달력의 백 로그 목록이 나를 때리면서 소리 지르기 시작했습니다.

내 두 센트


5
감사. 이 게시물을 작성하는 대신 작업을 수행 했어야합니다. 하하
Ragi Yaser Burhum

3
+1 귀하의 의견을 보내 주셔서 감사합니다. Mr. Burhum. 이것이 내가 받고자하는 응답의 유형입니다. 내가 그것을 두 번 투표 할 수 있다면 나는 할 수 있었다!! ArcGISScripting (python) 사용자가이 답변에서 가져와야하는 것은 링크가 ArcObjects 및 .Net 개념을 반영하지만 기본 COM 객체는 동일하지만 이러한 객체를 이해하면 모든 언어로 코드를 더 잘 계획하는 데 도움이됩니다. 여기에 많은 훌륭한 정보가 있습니다 !!
OptimizePrime

1
@OptimizePrime 훌륭한 요약입니다. 그리고 당신은 옳습니다-ESRI 제품의 성능을 짜내려면 ArcObjects의 의미를 무시할 수 없습니다
Ragi Yaser Burhum

1
덕분에 store ()를 커서를 삽입하여 대체하고 응용 프로그램에서 많은 시간을 절약했습니다!
superrache

5

일반적으로 성능 계산을 위해 ESRI 관련 항목을 사용하지 않으려 고합니다. 예를 들어, 프로세스를 단계별로 수행하고, 첫 번째 단계는 데이터를 일반 파이썬 객체로 읽고 계산을 한 다음 마지막 단계는 최종 ESRI 공간 형식으로 변환하는 것이 좋습니다. ~ 10k 레코드의 경우 처리를 위해 메모리에 모든 것을 저장하여 벗어날 수 있으며 이는 확실한 성능 향상을 제공합니다.


당신의 응답을 주셔서 감사합니다. 좋은 제안입니다. arcgisscripting을 사용하기 전에 필요한 절차를 수행하기 위해 코드를 리팩터링하기 시작했습니다. ArcInfo 시절 이후 소프트웨어로 작업 한 후 CPU 성능 및 하드웨어 기능이 향상되는 것을 실망스럽게 생각하면 ArcGIS Map / Info / Editor XX 성능이 정체되었습니다. GPU의 도입으로 인해 문제가 발생할 수 있습니다. ESRI 코드베이스의 좋은 리 팩터가 도움이 될 수도 있지만
OptimizePrime

1

보유한 하드웨어에 따라 ESRI Geocoder 예에 표시된 옵션을 고려할 수도 있습니다. 그것은 큰 데이터 세트를 분해하고 파이썬의 여러 인스턴스를 실행하여 거의 멀티 스레드 방식을 제공하는 프레임 워크를 제공합니다. 내 컴퓨터에서 8 개의 병렬 프로세스를 회전시켜 단일 Python 인스턴스에서 시간당 180,000에서 백만 이상으로 지오 코딩 성능이 향상되는 것을 보았습니다.

가능한 한 멀리 떨어져 데이터베이스에서 데이터 작업을 유지하고 테이블에서 기능 작업을 수행하고 ESRI 영역에서 명시 적 GIS를 사용하면 성능이 크게 향상됩니다.


이것들은 좋은 생각입니다. 이 스크립트에서 일부 프로세스를 스레드 할 수 있지만 병목이 COM 라이브러리 및 Geodatabase I / O를 초기화하고 있음을 발견했습니다. I / O와 관련하여 단일 쓰기의 필요성을 줄였습니다. 더 이상 최적화하는 데 시간을 보내면 상사는 적합 할 것입니다.) 따라서 더 많은 것을 요구하면 스레딩을 성능의 마지막 스퀴즈로 남겨 둡니다. 현재 분당 60,000 개의 기능을 처리하고 있습니다.
OptimizePrime

0

이 다른 포럼 게시물은 최적화 컨텍스트에 있지만 래스터 데이터 및 전체에 대해 흥미로운 것을 찾을 수 있습니다.

ArcGIS Geoprocessing Tools를 사용하는 Python 스크립트를 컴파일 하시겠습니까?

독립형 Python 스크립트 대 ArcCatalog에서 ArcGIS Hydrology 도구 상자 도구를 사용하여 처리 시간?

gp.scratchworkspace 설정은 유역 묘사를 위해 작성한 파이썬 코드에서 크게 달라졌습니다.

UPDATE에서 숫자 1과 2를 보여주는 코드 예제를 원래 질문에 게시 할 수 있습니까? 나는 그 역학을보고 싶을 것이다 (여기서 당신이 피쳐 클래스 데이터 만 다루고 있다고 가정하지만)

고마워, 톰

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.