Hiệu suất của ArcGISScripting và các bộ dữ liệu không gian lớn


38

Tôi hiện đang viết một tập lệnh python bằng cách sử dụng mô-đun arcgisscripting để xử lý một tập dữ liệu lớn tương đối (tổng cộng 10.000 bản ghi) được chuẩn hóa trên một số lượng nhỏ các bảng, tổng cộng 8 bảng. Quá trình này bao gồm việc tạo một tính năng dựa trên các bộ tọa độ (x, y) và tạo một biểu đồ (nút và đường) bằng cách sử dụng các mối quan hệ trong 7 bảng khác để được hướng dẫn. Đầu ra cuối cùng là một cơ sở dữ liệu địa lý cá nhân (pgdb / fgdb) với các nút và các bộ dữ liệu không gian cạnh thể hiện trực quan các mối quan hệ.

Nỗ lực ban đầu của tôi là sử dụng các truy vấn của các bảng cơ sở dữ liệu địa lý mới và các bộ bản ghi SearchCoder để điền vào các bảng liên kết (Chèn mã hóa) cho các mối quan hệ nhiều-nhiều xảy ra. Điều này làm việc rất tốt, ngoại trừ thời gian xử lý 15-20 phút.

Sử dụng mô-đun cProfiler trong Python, rõ ràng việc 'đập' cơ sở dữ liệu địa lý cá nhân khi thực hiện các truy vấn tìm kiếm để điền vào các bảng liên kết với các yêu cầu cho con trỏ (Tìm kiếm và chèn con trỏ) gây ra hiệu suất kinh khủng.

Với một chút tái cấu trúc, tôi đã có được thời gian xử lý dưới 2,5 phút. Sự đánh đổi là việc xây dựng một phần lược đồ cơ sở dữ liệu địa lý trong mã và giới hạn các yêu cầu đối với con trỏ mô tả cung cho Trình điều khiển khi tất cả các mối quan hệ được đối chiếu.

Câu hỏi của tôi là một trong những hiệu suất;

  • Những kỹ thuật nào mọi người đã sử dụng để duy trì thời gian tính toán hợp lý khi làm việc với tập dữ liệu lớn?
  • Có phương pháp ESRI nào được đề xuất mà tôi đã bỏ lỡ trong quá trình tìm kiếm để tối ưu hóa không?

    Tôi hiểu chi phí phát sinh khi tạo con trỏ hình cung, đặc biệt nếu đó là từ cơ sở dữ liệu địa lý cá nhân, mặc dù sau một thời gian dài tìm kiếm các câu trả lời liên quan đến hiệu suất từ ​​trang web này và Google tôi có ấn tượng rằng hiệu suất không đi đầu trong nỗ lực của mọi người .

  • Là người dùng các sản phẩm ESRI, liệu người ta có mong đợi và bỏ qua các độ trễ hiệu suất này không?

CẬP NHẬT

Sau một số công việc với sản phẩm này, tôi đã tích lũy được một danh sách các kỹ thuật tối ưu hóa đã thực hiện quá trình chuyển đổi thông tin không gian từ định dạng sở hữu sang cơ sở dữ liệu địa lý. Điều này đã được phát triển cho cơ sở dữ liệu địa lý cá nhân và tập tin. Các mẩu tin:

  1. Đọc dữ liệu của bạn và hợp lý hóa nó trong bộ nhớ. Điều này sẽ cắt giảm thời gian của bạn một nửa.

  2. Tạo các lớp tính năng và bảng trong bộ nhớ. Sử dụng khóa dữ liệu tính năng 'in_memory' để sử dụng bộ nhớ của bạn dưới dạng đĩa ram, thực hiện các chức năng của bạn ở đó và sau đó ghi ra đĩa

  3. Để ghi ra đĩa, hãy sử dụng CopyFeatureclass cho các lớp đối tượng và CopyRow cho các bảng.

3 điều này đã lấy một tập lệnh chuyển đổi hơn 100.000 tính năng sang cơ sở dữ liệu địa lý từ 30 phút đến 30 - 40 giây, bao gồm các lớp quan hệ. Chúng không được sử dụng một cách nhẹ nhàng, hầu hết các phương pháp trên đều sử dụng nhiều bộ nhớ, điều này có thể gây ra sự cố cho bạn nếu bạn không chú ý.


1
Bạn đã thử sử dụng một định dạng lưu trữ khác nhau? Làm thế nào để một tập tin geodatabase thực hiện?
Derek Swingley

Cơ sở dữ liệu địa lý tệp thực hiện kém hơn một chút so với cơ sở dữ liệu địa lý cá nhân. Tôi đã dành ngày hôm qua để thiết lập và điều chỉnh một phiên bản ArcSDE để kiểm tra hiệu suất trên định dạng doanh nghiệp. Tôi sẽ thông báo cho bạn về những phát hiện của tôi
OptimizePrime

2
Điều này không giúp ích gì cho bạn bây giờ, nhưng hiệu suất con trỏ 10.1 trong Python đã được cải thiện nhờ một yếu tố rất lớn (thứ gì đó theo thứ tự phạm vi cường độ trung bình) với mô-đun truy cập dữ liệu mới.
Jason Scheirer

Sử dụng In_memory một sự InMemoryWorkspace edndoc.esri.com/arcobjects/9.2/ComponentHelp/esriDataSourcesGDB/... đó, sau khi một số tùy ý của các hàng, bãi mọi thứ đến một ScratchWorkspaceFactory (tức FileGDB) và dựa vào FileGDB để làm tất cả công việc
Ragi Yaser Burhum

Câu trả lời:


56

Mặc dù câu hỏi này đã được trả lời, tôi nghĩ rằng tôi có thể kêu vang trong việc đưa ra hai xu của mình.

TUYÊN BỐ TỪ CHỐI : Tôi đã làm việc cho ESRI tại nhóm GeoDatabase trong một số năm và chịu trách nhiệm duy trì các phần khác nhau của mã GeoDatabase (Phiên bản, Con trỏ, Chỉnh sửa, Lịch sử, Lớp học Mối quan hệ, v.v.).

Tôi nghĩ rằng nguồn lớn nhất của các vấn đề về hiệu năng với mã ESRI là không hiểu ý nghĩa của việc sử dụng các đối tượng khác nhau, đặc biệt là các chi tiết "nhỏ" của các tóm tắt GeoDatabase khác nhau! Vì vậy, rất thường xuyên, cuộc trò chuyện chuyển sang ngôn ngữ đang được sử dụng như là thủ phạm của các vấn đề hiệu suất. Trong một số trường hợp nó có thể được. Nhưng không phải lúc nào cũng vậy. Hãy bắt đầu với cuộc thảo luận ngôn ngữ và làm việc theo cách của chúng tôi.

1.- Ngôn ngữ lập trình mà bạn chọn chỉ quan trọng khi bạn đang làm một việc gì đó phức tạp, trong một vòng lặp chặt chẽ. Hầu hết thời gian, đây không phải là trường hợp.

Con voi lớn trong phòng là cốt lõi của tất cả các mã ESRI, bạn có ArcObjects - và ArcObjects được viết bằng C ++ bằng COM . Có một chi phí để giao tiếp với mã này. Điều này đúng với C #, VB.NET, python hoặc bất cứ thứ gì bạn đang sử dụng.

Bạn phải trả giá khi khởi tạo mã đó. Đó có thể là một chi phí không đáng kể nếu bạn chỉ làm một lần.

Sau đó, bạn phải trả giá cho mỗi lần tiếp theo bạn tương tác với ArcObjects.

Cá nhân, tôi có xu hướng viết mã cho khách hàng của mình bằng C #, vì nó dễ dàng và đủ nhanh. Tuy nhiên, mỗi khi tôi muốn di chuyển dữ liệu xung quanh hoặc thực hiện một số xử lý cho một lượng lớn dữ liệu đã được triển khai trong Công cụ địa lý, tôi chỉ khởi tạo hệ thống con tập lệnh và chuyển các tham số của mình. Tại sao?

  • Nó đã được thực hiện. Vậy tại sao lại phát minh lại bánh xe?
  • Nó thực sự có thể nhanh hơn . "Nhanh hơn viết nó bằng C #?" Vâng! Nếu tôi thực hiện, giả sử, tải dữ liệu theo cách thủ công, điều đó có nghĩa là tôi phải trả giá chuyển đổi bối cảnh .NET theo một vòng lặp chặt chẽ. Mỗi GetValue, Chèn, ShapeCopy đều có chi phí. Nếu tôi thực hiện một cuộc gọi trong GP, toàn bộ quá trình tải dữ liệu sẽ xảy ra trong quá trình thực hiện GP - trong C ++ trong môi trường COM. Tôi không trả giá cho việc chuyển đổi ngữ cảnh vì không có gì - và do đó nó nhanh hơn.

À đúng rồi, vậy thì giải pháp nếu sử dụng nhiều chức năng xử lý địa lý. Thật ra, bạn phải cẩn thận.

2. GP là một hộp đen sao chép dữ liệu (có thể không cần thiết) xung quanh

Nó là một con dao hai lưỡi. Đó là một hộp đen thực hiện một số phép thuật trong nội bộ và tạo ra kết quả - nhưng những kết quả đó rất thường được nhân đôi. 100.000 hàng có thể dễ dàng được chuyển đổi thành 1.000.000 hàng trên đĩa sau khi bạn chạy dữ liệu của mình thông qua 9 chức năng khác nhau. Chỉ sử dụng các hàm GP cũng giống như tạo mô hình GP tuyến tính, và ...

3. Xâu chuỗi quá nhiều hàm GP cho các bộ dữ liệu lớn rất kém hiệu quả. Mô hình GP tương đương (có khả năng) tương đương với thực hiện truy vấn theo cách thực sự thực sự thực sự ngu ngốc

Bây giờ đừng hiểu lầm tôi. Tôi yêu GP Model - nó tiết kiệm cho tôi khỏi việc viết mã mọi lúc. Nhưng tôi cũng nhận thức được rằng đó không phải là cách hiệu quả nhất để xử lý các bộ dữ liệu lớn.

Bạn đã từng nghe nói về Query Planner chưa? Công việc của bạn là xem xét câu lệnh SQL mà bạn muốn thực thi, tạo một kế hoạch thực hiện dưới dạng biểu đồ có hướng trông giống như một Mô hình GP , xem các số liệu thống kê được lưu trữ trong db và chọn nhiều nhất thứ tự tối ưu để thực hiện chúng . GP chỉ thực hiện chúng theo thứ tự bạn đặt mọi thứ vì nó không có số liệu thống kê để làm bất cứ điều gì thông minh hơn - bạn là người lập kế hoạch truy vấn . Và đoán xem? Thứ tự mà bạn thực hiện mọi thứ phụ thuộc rất nhiều vào tập dữ liệu của bạn. Thứ tự mà bạn thực hiện mọi thứ có thể tạo ra sự khác biệt giữa ngày và giây và đó là tùy thuộc vào bạn để quyết định.

"Tuyệt vời" bạn nói, tôi sẽ không tự viết kịch bản và cẩn thận về cách tôi viết nội dung. Nhưng bạn có hiểu trừu tượng GeoDatabase không?

4.Không hiểu trừu tượng GeoDatabase có thể dễ dàng cắn bạn

Thay vì chỉ ra từng điều có thể có thể gây ra cho bạn một vấn đề, hãy để tôi chỉ ra một vài lỗi phổ biến mà tôi thấy mọi lúc và một số khuyến nghị.

  • Hiểu sự khác biệt giữa Đúng / Sai đối với con trỏ Tái chế . Cờ nhỏ bé này được đặt thành đúng có thể làm cho các đơn đặt hàng thời gian chạy nhanh hơn.
  • Đặt bảng của bạn vào LoadOnlyMode để tải dữ liệu. Tại sao cập nhật chỉ mục trên mỗi chèn?
  • Hiểu rằng mặc dù IWorkspaceEdit :: StartEditing trông giống nhau trong tất cả các không gian làm việc, chúng là những con thú rất khác nhau trên mỗi nguồn dữ liệu. Trên Enterprise GDB, bạn có thể có phiên bản hoặc hỗ trợ cho các giao dịch. Trên shapefiles, nó sẽ phải được thực hiện theo một cách rất khác. Làm thế nào bạn sẽ thực hiện Hoàn tác / Làm lại? Bạn thậm chí có cần phải kích hoạt nó không (vâng, nó có thể tạo ra sự khác biệt trong việc sử dụng bộ nhớ).
  • Sự khác biệt giữa các hoạt động hàng loạt, hoặc hoạt động hàng đơn. Trường hợp tại điểm GetRow so với GetRows - đây là sự khác biệt giữa thực hiện truy vấn để có một hàng hoặc thực hiện một truy vấn để tìm nạp nhiều hàng. Một vòng lặp chặt chẽ với một cuộc gọi đến GetRow có nghĩa là hiệu suất khủng khiếp và nó là thủ phạm số 1 của các vấn đề về hiệu suất
  • Sử dụng UpdateSearchedRows
  • Hiểu sự khác biệt giữa CreatRowCreateRowBuffer . Sự khác biệt lớn trong thời gian chạy chèn.
  • Hiểu rằng IRow :: Store và IFeature :: Store kích hoạt các hoạt động đa hình siêu nặng . Đây có lẽ là lý do số 2 thủ phạm của hiệu suất thực sự chậm. Không chỉ lưu hàng, đây là phương pháp đảm bảo mạng hình học của bạn ổn, Trình soạn thảo ArcMap được thông báo rằng một hàng đã thay đổi, thông báo tất cả các lớp quan hệ có liên quan đến hàng này để xác thực chắc chắn rằng giá trị thẻ là hợp lệ, v.v. Bạn không nên chèn các hàng mới với điều này, bạn nên sử dụng một Chèn !
  • Bạn có muốn (cần) thực hiện các thao tác chèn đó trong EditSession không? Nó làm cho một sự khác biệt rất lớn nếu bạn làm hay không. Một số thao tác yêu cầu nó (và làm mọi thứ chậm hơn), nhưng khi bạn không cần nó, hãy bỏ qua các tính năng hoàn tác / làm lại.
  • Con trỏ là tài nguyên đắt tiền. Khi bạn đã xử lý một, bạn được đảm bảo rằng bạn sẽ có Tính nhất quán và Cách ly và điều đó có chi phí.
  • Lưu trữ các tài nguyên khác như kết nối cơ sở dữ liệu (không tạo và hủy tham chiếu Vùng làm việc của bạn) và Bảng điều khiển (mỗi khi bạn mở hoặc đóng một tài khoản - cần phải đọc một số bảng siêu dữ liệu).
  • Đặt FeatureClass bên trong hoặc bên ngoài FeatureDataset tạo ra sự khác biệt lớn về hiệu suất. Nó không có nghĩa là một tính năng tổ chức!

5.Và cuối cùng và không kém ...

Hiểu sự khác biệt giữa các hoạt động ràng buộc I / O và CPU

Tôi thành thật nghĩ về việc mở rộng nhiều hơn trên từng mục một và có thể thực hiện một loạt các mục blog bao gồm từng chủ đề đó, nhưng danh sách tồn đọng trong lịch của tôi chỉ tát vào mặt tôi và bắt đầu la hét với tôi.

Hai xu của tôi.


5
cảm ơn. Lẽ ra tôi nên làm việc thay vì viết bài này haha
Ragi Yaser Burhum

3
+1 Cảm ơn bạn rất nhiều vì đầu vào của bạn Mr Burhum. Đây là loại phản ứng tôi đã nhắm đến để nhận được. Nếu tôi có thể bỏ phiếu hai lần tôi có thể !! Những gì người dùng ArcGISScripting (python) nên lấy từ câu trả lời này là, mặc dù các liên kết phản ánh các khái niệm ArcObjects và .Net, các đối tượng COM bên dưới là như nhau, hiểu các đối tượng này sẽ giúp bạn lập kế hoạch mã tốt hơn trong bất kỳ ngôn ngữ nào. Rất nhiều thông tin tuyệt vời ở đây !!
OptimizePrime

1
@OptizesPrime Đó là một bản tóm tắt tuyệt vời. Và bạn đã đúng - bạn không thể bỏ qua các hàm ý của ArcObjects nếu bạn muốn loại bỏ hiệu suất khỏi các sản phẩm ESRI
Ragi Yaser Burhum

1
cảm ơn, tôi đã thay thế store () bằng cách chèn con trỏ và tiết kiệm rất nhiều thời gian trong các ứng dụng của mình!
superrache

5

Nói chung, để tính toán hiệu suất, tôi cố gắng tránh sử dụng bất kỳ nội dung nào liên quan đến ESRI. Ví dụ của bạn, tôi khuyên bạn nên thực hiện quy trình theo các bước, bước đầu tiên đọc dữ liệu vào các đối tượng python bình thường, thực hiện các phép tính và sau đó là bước cuối cùng chuyển đổi sang định dạng không gian ESRI cuối cùng. Đối với các bản ghi ~ 10k, có lẽ bạn có thể thoát khỏi việc lưu trữ mọi thứ trong bộ nhớ để xử lý, điều này sẽ mang lại hiệu suất rõ ràng.


Cảm ơn bạn đã phản hồi của bạn. Đó là một gợi ý tốt. Tôi đã bắt đầu cấu trúc lại mã để thực hiện các quy trình cần thiết trước khi sử dụng arcgisscripting. Sau khi làm việc với phần mềm kể từ ngày ArcInfo của tôi, tôi thấy bực bội vì hiệu suất CPU và khả năng Phần cứng tăng lên, hiệu suất ArcGIS Map / Info / Editor XX bị đình trệ. Có lẽ việc giới thiệu GPU có thể thúc đẩy mọi thứ. Mặc dù một công cụ tái cấu trúc tốt của cơ sở mã ESRI cũng có thể giúp
OptimizePrime

1

Tùy thuộc vào phần cứng bạn có, bạn cũng có thể xem xét tùy chọn được hiển thị trong Ví dụ Trình mã hóa ESRI; nó cung cấp cho bạn một khung để chia nhỏ một tập dữ liệu lớn và chạy nhiều phiên bản của python để cung cấp cho bạn một cách tiếp cận đa luồng. Tôi thấy hiệu suất mã hóa địa lý tăng từ 180.000 mỗi giờ trong một trường hợp Python duy nhất lên hơn một triệu nhờ vào việc quay vòng 8 quy trình song song trên máy của tôi.

Tôi đã thấy rằng việc lấy đi càng nhiều càng tốt và giữ cho dữ liệu hoạt động trong cơ sở dữ liệu, và hoạt động chức năng trong các bảng của tôi và chỉ sử dụng những gì rõ ràng là GIS trong lĩnh vực ESRI giúp tăng hiệu suất lớn.


Đây là những ý tưởng tuyệt vời. Tôi có cơ hội xâu chuỗi một số quy trình trong kịch bản này, nhưng tôi thấy cổ chai của mình đang khởi tạo các thư viện COM và I / O Geodatabase. Liên quan đến I / O, tôi đã giảm nhu cầu viết một lần. Nếu tôi dành thêm thời gian để tối ưu hóa, sếp của tôi sẽ có một sự phù hợp;) Vì vậy, tôi sẽ rời khỏi luồng như là sự siết chặt cuối cùng của hiệu suất nếu anh ta yêu cầu nhiều hơn. Hiện tại tôi đang xử lý 60.000 tính năng một phút.
OptimizePrime

0

Bạn có thể thấy các bài đăng trên diễn đàn khác thú vị vì chúng nằm trong bối cảnh tối ưu hóa nhưng đối với dữ liệu raster và tổng thể:

Biên dịch tập lệnh Python sử dụng Công cụ xử lý địa lý ArcGIS?

Thời gian xử lý bằng cách sử dụng các công cụ hộp công cụ ArcGIS Hydrology trong tập lệnh Python độc lập so với ArcCatalog?

cài đặt gp.scratchworkspace tạo ra sự khác biệt lớn đối với tôi trong một số mã python tôi đã viết để thực hiện các phân định đầu nguồn.

Bạn có thể đăng một số ví dụ mã chứng minh số 1 và 2 trong CẬP NHẬT của bạn cho câu hỏi ban đầu của bạn không? Tôi rất muốn thấy cơ chế của điều đó (mặc dù tôi cho rằng bạn chỉ xử lý dữ liệu lớp tính năng ở đây)

cảm ơn, Tom

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.