Najszybszy sposób na policzenie liczby funkcji w klasie obiektów?

35

Po wprowadzeniu modułu Data Access w Arcpy (30x szybsze kursory wyszukiwania) chcę wiedzieć, czy liczenie funkcji spełniających kryteria SQL jest szybsze niż tradycyjna metodologia MakeTableView + GetCount?

Michał Markieta
źródło
12
Jak głupie jest to, że liczba funkcji nie jest tylko własnością arcpy.Describe object
Grant Humphries
To było całkiem łatwe z ogrinfo z pewnym OGR SQL . Zestaw danych zawiera coś w rodzaju 170000 rekordów, a wyszukiwanie symboli wieloznacznych w nieindeksowanym VARCHARpolu powróciło w ciągu kilku sekund. ogrinfo "C:\xGIS\Vector\parcels\parcels_20140829_pmerc.ovf -sql "SELECT count(*) FROM parcels_20140829_pmerc WHERE tms like 'R39200-02-%'"
elrobis

Odpowiedzi:

2

Testowałem rozwiązanie z powyższej odpowiedzi i na moich rzeczywistych danych różnica jest znikoma. W przeciwieństwie do innych odpowiedzi, moje czasy dla arcpy.MakeTableView_management i arcpy.da.SearchCursor w ArcMap są takie same.

Testowałem odmiany z zapytaniem i bez niego, zobacz kod wersji zapytania i końcowe wyniki pomiaru poniżej:

@staticmethod
def query_features(feature_class, query):

    # Method 1
    time.sleep(5)  # Let the cpu/ram calm before proceeding!
    start_time = time.clock()
    count = len(list(i for i in arcpy.da.SearchCursor(feature_class, ["OBJECTID"], query)))
    end_time = time.clock()
    arcpy.AddMessage("Method 1 finished in {} seconds".format((end_time - start_time)))
    arcpy.AddMessage("{} features".format(count))

    # Method 2
    time.sleep(5)  # Let the cpu/ram calm before proceeding!
    start_time = time.clock()
    arcpy.MakeTableView_management(feature_class, "myTableView", query)
    count = int(arcpy.GetCount_management("myTableView").getOutput(0))

    end_time = time.clock()
    arcpy.AddMessage("Method 2 in {} seconds".format((end_time - start_time)))
    arcpy.AddMessage("{} features".format(count))

Wyniki poniżej:

    No query:
    Method 1 finished in 5.3616442 seconds
    804140 features
    Method 2 in 4.2843138 seconds
    804140 features

    Many results query:
    Method 1 finished in 12.7124766 seconds
    518852 features
    Method 2 in 12.1396602 seconds
    518852 features

    Few results query:
    Method 1 finished in 11.1421476 seconds
    8 features
    Method 2 in 11.2232503 seconds
    8 features
Miro
źródło
Cóż, minęło około 7 lat od odpowiedzi na pytanie, więc mam nadzieję, że wprowadzili ulepszenia do swojego SDK !!! =) dzięki za testowanie go sam Miro.
Michael Markieta
47

Korzystam z przykładu z 1 milionem losowo wygenerowanych punktów wewnątrz bazy danych. Załączony tutaj .

Oto kod, od którego możemy zacząć:

import time
import arcpy

arcpy.env.workspace = "C:\CountTest.gdb"

time.sleep(5) # Let the cpu/ram calm before proceeding!

"""Method 1"""
StartTime = time.clock()
with arcpy.da.SearchCursor("RandomPoints", ["OBJECTID"]) as cursor:
    rows = {row[0] for row in cursor}

count = 0
for row in rows:
    count += 1

EndTime = time.clock()
print "Finished in %s seconds" % (EndTime - StartTime)
print "%s features" % count

time.sleep(5) # Let the cpu/ram calm before proceeding!

"""Method 2"""
StartTime2 = time.clock()
arcpy.MakeTableView_management("RandomPoints", "myTableView")
count = int(arcpy.GetCount_management("myTableView").getOutput(0))

EndTime2 = time.clock()
print "Finished in %s seconds" % (EndTime2 - StartTime2)
print "%s features" % count

I kilka wstępnych wyników:

>>> 
Finished in 6.75540050237 seconds
1000000 features
Finished in 0.801474780332 seconds
1000000 features
>>> =============================== RESTART ===============================
>>> 
Finished in 6.56968596918 seconds
1000000 features
Finished in 0.812731769756 seconds
1000000 features
>>> =============================== RESTART ===============================
>>> 
Finished in 6.58207512487 seconds
1000000 features
Finished in 0.841122157314 seconds
1000000 features

Wyobraź sobie większe, bardziej złożone zbiory danych. SearchCursor będzie się czołgał w nieskończoność.

Nie jestem wcale niezadowolony z wyników, jednak moduł DataAccess jest szeroko stosowany w naszym środowisku programistycznym GIS. Chcę odbudować niektóre z naszych definicji funkcji za pomocą tego modułu, ponieważ jest on bardziej elastyczny niż metodologia MakeTableView + GetCount.

Michał Markieta
źródło
Niezła łapanka. Dla kompletności chciałbym dodać, która IMO powinna być najszybsza, ale w rzeczywistości jest to najwolniejsza metoda (10x wolniejsza). arcpy.Statistics_analysis("RandomPoints", r"in_memory\count", [["OBJECTID", "COUNT"]]) cursor = arcpy.da.SearchCursor(r"in_memory\count", ["COUNT_OBJECTID"]) row = cursor.next() del cursor count = row[0]
Berend,