Kinerja skrip ArcGISS dan kumpulan data spasial yang besar

38

Saat ini saya sedang menulis skrip python menggunakan modul arcgisscripting untuk memproses set data yang cukup besar (~ total 10.000 catatan) dinormalisasi atas sejumlah kecil tabel, 8 total. Proses ini terdiri dari membuat fitur berdasarkan koordinat tupel (x, y) dan membuat grafik (node ​​dan garis) menggunakan hubungan di 7 tabel lainnya untuk panduan. Hasil akhir adalah geodatabase pribadi (pgdb / fgdb) dengan kumpulan data spasial node dan tepi yang secara visual mewakili hubungan.

Upaya awal saya adalah menggunakan kueri dari tabel geodatabase baru dan set catatan SearchCursor untuk mengisi tabel tautan (InsertCursor) untuk hubungan banyak ke banyak yang terjadi. Ini bekerja dengan sangat baik, kecuali untuk waktu pemrosesan 15-20 menit.

Menggunakan modul cProfiler dengan Python, tampak jelas bahwa 'meronta-ronta' sebuah geodatabase pribadi ketika melakukan permintaan pencarian untuk mengisi tabel tautan dengan permintaan kursor (Cari dan Masukkan kursor) menyebabkan kinerja yang mengerikan.

Dengan sedikit refactoring saya berhasil mendapatkan waktu pemrosesan di bawah 2,5 menit. Trade off adalah pembangunan sebagian skema geodatabase dalam kode dan membatasi permintaan untuk kursor arccisscripting ke InsertCursors setelah semua hubungan disusun.

Pertanyaan saya adalah tentang kinerja;

  • Teknik apa yang digunakan orang untuk menjaga waktu komputasi yang masuk akal ketika bekerja dengan kumpulan data besar?
  • Apakah ada metode yang direkomendasikan ESRI yang saya lewatkan dalam pencarian saya untuk optimasi?

    Saya memahami overhead yang terjadi ketika membuat kursor arcgisscripting, terutama jika itu dari geodatabase pribadi, meskipun setelah pencarian panjang untuk jawaban terkait kinerja dari situs ini dan Google, saya mendapat kesan bahwa kinerja tidak berada di garis depan upaya masyarakat. .

  • Sebagai pengguna produk ESRI, apakah orang mengharapkan dan memaafkan keterlambatan kinerja ini?

MEMPERBARUI

Setelah beberapa pekerjaan dengan produk ini saya telah mengumpulkan daftar teknik optimasi yang telah mengambil proses mengubah informasi spasial dari format hak milik ke geodatabase. Ini telah dikembangkan untuk personal dan file geodatabase. Informasi:

  1. Membaca data Anda dan merasionalisasikannya dalam memori. Ini akan memotong waktu Anda menjadi dua.

  2. Buat kelas fitur dan tabel dalam memori. Gunakan fitur kunci kumpulan data 'in_memory' untuk menggunakan memori Anda sebagai ram disk, jalankan fungsi Anda di sana, lalu tuliskan ke disk

  3. Untuk menulis ke disk gunakan CopyFeatureclass untuk kelas fitur, dan CopyRow untuk tabel.

Ketiga hal ini mengambil skrip yang mengubah 100.000+ fitur ke geodatabase dari 30 menit menjadi 30 - 40 detik, ini termasuk kelas hubungan. Mereka tidak dapat digunakan dengan ringan, sebagian besar metode di atas menggunakan banyak memori, yang dapat menyebabkan Anda masalah jika Anda tidak memperhatikan.

OptimizePrime
sumber
1
Sudahkah Anda mencoba menggunakan format penyimpanan yang berbeda? Bagaimana kinerja file geodatabase?
Derek Swingley
File geodatabase berperforma sedikit lebih buruk daripada geodatabase pribadi. Saya telah menghabiskan kemarin mengatur dan menyetel instance ArcSDE untuk menguji kinerja pada format perusahaan. Saya akan terus memberi Anda informasi tentang temuan saya
OptimizePrime
2
Ini tidak membantu Anda sekarang, tetapi dalam kinerja kursor 10,1 di Python telah ditingkatkan oleh faktor besar (sesuatu dalam urutan rentang besarnya pada kasus rata-rata) dengan modul akses data baru.
Jason Scheirer
In_memory menggunakan sebuah yang InMemoryWorkspace edndoc.esri.com/arcobjects/9.2/ComponentHelp/esriDataSourcesGDB/... yang, setelah jumlah sewenang-wenang baris, kesedihan segala sesuatu ke ScratchWorkspaceFactory (yaitu FileGDB) dan bergantung pada FileGDB untuk melakukan semua pekerjaan
Ragi Yaser Burhum

Jawaban:

56

Meskipun pertanyaan ini sudah dijawab, saya pikir saya bisa berpadu memberi dua sen.

PENOLAKAN : Saya bekerja untuk ESRI di tim GeoDatabase selama beberapa tahun dan bertanggung jawab untuk memelihara berbagai bagian kode GeoDatabase (Versi, Kursor, EditSessions, Sejarah, Kelas Hubungan, dll.).

Saya pikir sumber terbesar masalah kinerja dengan kode ESRI tidak memahami implikasi menggunakan objek yang berbeda, khususnya, detail "kecil" dari berbagai abstraksi GeoDatabase! Sangat sering, percakapan beralih ke bahasa yang digunakan sebagai biang keladi masalah kinerja. Dalam beberapa kasus bisa jadi. Tapi tidak setiap saat. Mari kita mulai dengan diskusi bahasa dan kembali lagi.

1.- Bahasa pemrograman yang Anda pilih hanya penting ketika Anda melakukan sesuatu yang rumit, dalam lingkaran yang ketat. Sebagian besar waktu, ini tidak terjadi.

Gajah besar di ruangan itu adalah inti dari semua kode ESRI, Anda memiliki ArcObjects - dan ArcObjects ditulis dalam C ++ menggunakan COM . Ada biaya untuk berkomunikasi dengan kode ini. Ini berlaku untuk C #, VB.NET, python, atau apa pun yang Anda gunakan.

Anda membayar harga saat inisialisasi kode itu. Itu mungkin biaya yang dapat diabaikan jika Anda melakukannya hanya sekali.

Anda kemudian membayar harga untuk setiap kali Anda berinteraksi dengan ArcObjects berikutnya.

Secara pribadi, saya cenderung menulis kode untuk klien saya di C #, karena mudah dan cukup cepat. Namun, setiap kali saya ingin memindahkan data atau melakukan pemrosesan untuk sejumlah besar data yang sudah diimplementasikan dalam Geoprocessing, saya hanya menginisialisasi subsistem scripting dan mengirimkan parameter saya. Mengapa?

  • Itu sudah diterapkan. Jadi mengapa menciptakan kembali kemudi?
  • Ini mungkin sebenarnya lebih cepat . "Lebih cepat daripada menulisnya dalam bahasa C #?" Iya nih! Jika saya menerapkan, katakanlah, memuat data secara manual, itu berarti saya membayar harga .NET switching konteks dalam loop yang ketat. Setiap GetValue, Insert, ShapeCopy memiliki biaya. Jika saya melakukan satu panggilan dalam GP, seluruh proses pemuatan data akan terjadi dalam implementasi aktual GP - dalam C ++ dalam lingkungan COM. Saya tidak membayar harga untuk pengalihan konteks karena tidak ada - dan karenanya lebih cepat.

Ah ya, jadi solusinya jika menggunakan banyak fungsi geoprocessing. Sebenarnya kamu harus hati-hati.

2. GP adalah kotak hitam yang menyalin data (mungkin tidak perlu) di sekitar

Itu adalah pedang bermata dua. Ini adalah kotak hitam yang melakukan beberapa sihir secara internal dan mengeluarkan hasil - tetapi hasil tersebut sangat sering diduplikasi. 100.000 baris dapat dengan mudah dikonversi menjadi 1.000.000 baris pada disk setelah Anda menjalankan data Anda melalui 9 fungsi yang berbeda. Hanya menggunakan fungsi GP seperti membuat model GP linier, dan ...

3. Merantai terlalu banyak fungsi GP untuk dataset besar sangat tidak efisien. Model GP (berpotensi) setara dengan mengeksekusi kueri dengan cara yang benar-benar sangat bodoh

Sekarang jangan salah paham. Saya suka Model GP - ini menyelamatkan saya dari menulis kode sepanjang waktu. Tetapi saya juga sadar bahwa ini bukan cara paling efisien untuk memproses kumpulan data besar.

Sudahkah Anda mendengar Perencana Kueri ? Tugasnya adalah untuk melihat pernyataan SQL yang ingin Anda jalankan, menghasilkan rencana eksekusi dalam bentuk grafik terarah yang terlihat banyak seperti Model GP , melihat statistik yang disimpan dalam db, dan memilih yang paling urutan optimal untuk menjalankannya . GP hanya mengeksekusi mereka dalam urutan Anda meletakkan sesuatu karena tidak memiliki statistik untuk melakukan sesuatu yang lebih cerdas - Anda adalah perencana kueri . Dan coba tebak? Urutan di mana Anda menjalankan sesuatu sangat tergantung pada dataset Anda. Urutan di mana Anda menjalankan sesuatu dapat membuat perbedaan antara hari dan detik dan itu terserah Anda untuk memutuskan.

"Hebat" katamu, aku tidak akan menulis naskah sendiri dan berhati-hati tentang bagaimana aku menulis barang. Tapi apakah Anda mengerti abstraksi GeoDatabase?

4.Tidak memahami abstraksi GeoDatabase dapat dengan mudah menggigit Anda

Alih-alih menunjukkan setiap hal yang mungkin dapat memberi Anda masalah, izinkan saya hanya menunjukkan beberapa kesalahan umum yang saya lihat sepanjang waktu dan beberapa rekomendasi.

  • Memahami perbedaan antara Benar / Salah untuk kursor Daur Ulang . Bendera kecil mungil ini disetel ke true dapat membuat runtime order magnitude lebih cepat.
  • Letakkan meja Anda di LoadOnlyMode untuk memuat data. Mengapa memperbarui indeks pada setiap sisipan?
  • Memahami bahwa meskipun IWorkspaceEdit :: StartEditing terlihat sama di semua ruang kerja, mereka adalah binatang yang sangat berbeda pada setiap sumber data. Pada Enterprise GDB, Anda mungkin memiliki versi atau dukungan untuk transaksi. Pada shapefile, itu harus diimplementasikan dengan cara yang sangat berbeda. Bagaimana Anda menerapkan Undo / Redo? Apakah Anda bahkan perlu mengaktifkannya (ya, itu dapat membuat perbedaan dalam penggunaan memori).
  • Perbedaan antara operasi batch, atau operasi baris tunggal. Contoh kasus GetRow vs GetRows - ini adalah perbedaan antara melakukan kueri untuk mendapatkan satu baris atau melakukan satu kueri untuk mengambil beberapa baris. Putaran ketat dengan panggilan ke GetRow berarti kinerja yang mengerikan dan merupakan penyebab masalah kinerja # 1
  • Gunakan UpdateSearchedRows
  • Memahami perbedaan antara CreateRow dan CreateRowBuffer . Perbedaan besar dalam runtime insert.
  • Memahami bahwa IRow :: Store dan IFeature :: Store memicu operasi polimorfik super berat . Ini mungkin alasan penyebab # 2 kinerja sangat lambat. Itu tidak hanya menyimpan baris, ini adalah metode yang memastikan jaringan geometrik Anda OK, bahwa ArcMap Editor mendapat pemberitahuan bahwa baris telah berubah, yang memberi tahu semua kelas hubungan yang ada hubungannya dengan baris ini valid untuk membuat Pastikan kardinalitasnya valid, dll. Anda seharusnya tidak memasukkan baris baru dengan ini, Anda harus menggunakan InsertCursor !
  • Apakah Anda ingin (perlu) melakukan sisipan tersebut di bagian EditSession? Itu membuat perbedaan besar jika Anda melakukannya atau tidak. Beberapa operasi memerlukannya (dan membuat segalanya lebih lambat), tetapi ketika Anda tidak membutuhkannya, lewati fitur undo / redo.
  • Kursor adalah sumber daya yang mahal. Setelah Anda memiliki pegangan ke satu, Anda dijamin bahwa Anda akan memiliki Konsistensi dan Isolasi dan yang memiliki biaya.
  • Tembolok sumber daya lain seperti koneksi basis data (jangan membuat dan menghancurkan referensi Workspace Anda) dan menangani Tabel (setiap kali Anda membuka atau menutup satu - beberapa tabel metadata perlu dibaca).
  • Menempatkan FeatureClasses di dalam atau di luar FeatureDataset membuat perbedaan besar dalam kinerja. Itu tidak dimaksudkan sebagai fitur organisasi!

5.Dan yang terakhir dan yang tidak kalah ...

Memahami perbedaan antara operasi terikat I / O dan terikat CPU

Jujur saya berpikir tentang memperluas lebih pada setiap satu dari item-item itu dan mungkin melakukan serangkaian entri blog yang mencakup setiap satu dari topik-topik itu, tetapi daftar simpanan kalender saya hanya menampar wajah saya dan mulai berteriak pada saya.

Dua sen saya.

Ragi Yaser Burhum
sumber
5
Terima kasih. Saya seharusnya melakukan pekerjaan daripada menulis posting ini haha
Ragi Yaser Burhum
3
+1 Terima kasih banyak atas masukan Anda, Pak Burhum. Ini adalah jenis respons yang ingin saya terima. Jika saya bisa memilih dua kali saya bisa !! Yang harus diambil oleh pengguna ArcGISScripting (python) dari jawaban ini adalah, meskipun tautannya mencerminkan ArcObjects dan .Net konsep, objek COM yang mendasarinya sama, memahami objek-objek ini akan membantu Anda merencanakan kode dengan lebih baik dalam bahasa apa pun. Banyak informasi hebat di sini !!
OptimizePrime
1
@OptimizePrime Itu ringkasan yang bagus. Dan Anda benar - Anda tidak dapat mengabaikan implikasi ArcObjects jika Anda ingin memeras kinerja produk ESRI
Ragi Yaser Burhum
1
terima kasih, saya mengganti store () dengan memasukkan kursor dan menghemat banyak waktu di aplikasi saya!
superrache
5

Secara umum, untuk perhitungan kinerja, saya mencoba untuk tidak menggunakan hal-hal terkait ESRI. Sebagai contoh Anda, saya akan menyarankan melakukan proses dalam langkah-langkah, langkah pertama membaca data menjadi objek python normal, melakukan perhitungan, dan kemudian langkah terakhir mengkonversi ke format spasial ESRI akhir. Untuk catatan ~ 10k, Anda mungkin bisa menyimpan semua dalam memori untuk pemrosesan, yang akan memberikan keuntungan kinerja yang pasti.

Anthony -GISCOE-
sumber
Terima kasih atas tanggapan Anda. Itu saran yang bagus. Saya sudah mulai memperbaiki kode untuk melakukan prosedur yang diperlukan sebelum menggunakan arcgisscripting. Setelah bekerja dengan perangkat lunak sejak masa ArcInfo, saya merasa frustasi karena kinerja CPU dan kemampuan Perangkat Keras meningkat, kinerja ArcGIS Map / Info / Editor XX mandek. Mungkin pengenalan GPU dapat meningkatkan banyak hal. Meskipun refactor basis kode ESRI yang baik dapat membantu juga
OptimizePrime
1

Bergantung pada perangkat keras yang Anda miliki, Anda mungkin juga mempertimbangkan opsi yang ditampilkan dalam Contoh ESRI Geocoder; itu memberi Anda kerangka kerja untuk memecah dataset besar dan menjalankan beberapa contoh python untuk memberi Anda hampir pendekatan multi-berulir. Saya melihat kinerja geocoding berubah dari 180.000 per jam dalam satu contoh Python menjadi lebih dari satu juta berkat untuk memutar 8 proses paralel pada mesin saya.

Saya telah melihat bahwa menjauh sebanyak yang saya bisa dan menjaga pekerjaan data dalam database, dan pekerjaan fungsional dalam tabel saya dan hanya menggunakan apa yang SIG eksplisit di bidang ESRI memberikan peningkatan kinerja besar.

Benar
sumber
Ini ide bagus. Saya memiliki kesempatan untuk merangkai beberapa proses dalam skrip ini, tetapi saya menemukan leher botol saya menginisialisasi perpustakaan COM dan Geodatabase I / O. Sehubungan dengan I / O, saya telah mengurangi kebutuhan untuk menulis tunggal. Jika saya menghabiskan lebih banyak waktu untuk mengoptimalkan, bos saya akan cocok;) Jadi saya meninggalkan threading sebagai pemerasan kinerja terakhir jika dia meminta lebih. Saat ini saya sedang memproses 60.000 fitur per menit.
OptimizePrime
0

Anda mungkin menemukan posting forum lain ini menarik karena berada dalam konteks optimisasi tetapi untuk data raster dan keseluruhan:

Mengkompilasi Skrip Python yang menggunakan ArcGIS Geoprocessing Tools?

Memproses waktu menggunakan alat toolbox ArcGIS Hidrologi dalam skrip Python mandiri vs ArcCatalog?

pengaturan gp.scratchworkspace membuat perbedaan besar bagi saya dalam beberapa kode python yang saya tulis untuk melakukan delineasi batas air.

Bisakah Anda memposting beberapa contoh kode yang menunjukkan angka 1 dan 2 di UPDATE Anda ke pertanyaan awal Anda? Saya akan tertarik untuk melihat mekanisme itu (meskipun saya berasumsi Anda hanya berurusan dengan data kelas fitur di sini)

terima kasih, Tom

turkishgold
sumber