Compilando scripts Python (para .exe) que usam as Ferramentas de Geoprocessamento do ArcGIS?


12

Estou codificando com Python há vários meses e desenvolvi alguns scripts razoavelmente complexos para tarefas principalmente de geoprocessamento. Dito isto, ainda estou aprendendo muito, pois venho de um background SQL / VBA / VBScript.

Eu sei que o código compilado normalmente é executado mais rapidamente do que o código que deve ser processado por um intérprete de linguagem, por isso estou interessado na possibilidade de compilar um script Python de geoprocessamento em um arquivo .EXE para trabalhar com big data.

Isso é possível? Se for, qual é a melhor maneira de compilar um script Python (.py) que esteja importando os módulos arcgisscripting ou arcpy?

Passei alguns minutos tentando encontrar o que quero fazer e a pesquisa retornou este artigo, entre outros: http://www.ehow.com/how_2091641_compile-python-code.html

O compilador parecia funcionar, mas, ao executar o arquivo .exe resultante, ocorreu um erro enigmático dizendo que alguns arquivos estavam indisponíveis.

O script Python executa o que parece razoavelmente bem a partir da linha de comando, mas estou me perguntando se eu poderia ver alguma leve melhora se fosse capaz de compilar o arquivo .py. Mais uma vez, estou trabalhando com alguns grandes conjuntos de dados que levam mais de 20 horas para serem processados ​​(delineando as bacias hidrográficas dos locais de amostra de qualidade da água). Vou levar tudo o que puder para melhorar.

O script foi executado 10% mais rápido fora do ArcGIS a partir da linha de comando, usando um conjunto de sites de teste versus a configuração do script como uma ferramenta de script em uma nova caixa de ferramentas no ArcCatalog. Eu tenho executado o script a partir da linha de comando sem qualquer instância do ArcGIS aberta em uma máquina dedicada.

Portanto, é possível compilar scripts Python que importam o módulo arcgisscripting e chamam as ferramentas ArcToolBox?

EDITAR

Obrigado pela contribuição, isso é útil para mim. O script é amplamente uma maneira de coordenar várias ferramentas do ArcGIS e gerar os formatos / locais desejados / com a atribuição apropriada. Acho que já reduzi um pouco de gordura, escrevendo em uma pasta de rascunho em vez de um geodatabase pessoal de rascunho para alguns arquivos raster temporários, para que eles possam ser armazenados no formato ESRI GRID versus no formato IMG. Vou verificar as sugestões do criador de perfil.

Há alguns no meu escritório que questionam o Python dizendo "que o código compilado é muito mais rápido que o código executado através de um intérprete", principalmente em comparação com, digamos, um programa Visual Basic ou VB.NET compilado, mas esse é um bom ponto as ferramentas vão levar tempo de qualquer maneira. E, parece que nas máquinas de computação atuais que interpretam código pode não ser muito mais lento que o código compilado para garantir que se esforce mais.

EDIT - atualização sobre otimização do programa com formatos raster.

Queria acompanhar a minha "otimização" deste programa Python, e pude economizar 2 horas de tempo de processamento escrevendo rasters provisórios no formato GRID em vez de em um geodatabase pessoal. Não apenas isso, houve uma redução significativa no consumo de espaço em disco no tamanho dos dados. A execução original que escrevi para todos os rasters (e eles eram apenas recursos pontuais convertidos em rasters e depois rasters de bacias hidrográficas) resultou em 37,1 GB de dados apenas para esses arquivos. A gravação das duas últimas saídas de dados em uma pasta no formato GRID foi reduzida para 667 MB de dados.

Eu ficaria curioso para ver como um arquivo GDB lidaria com esses dados, principalmente devido ao tamanho dos dados. Mas reduzir meu tempo de processamento de 9,5 para 7,5 horas certamente é suficiente para advogar por lidar com rasters fora dos bancos de dados geográficos no formato GRID.


Hoje, o Blog do ArcGIS Server é muito oportuno. Sterling @ esri faz um bom trabalho descrevendo por que e quando [aqui.] [1] [1]: blogs.esri.com/Dev/blogs/arcgisserver/archive/2011/04/12/…
Brad Nesom

Respostas:


15

Primeira pergunta: quanto disso você está fazendo no Python? Você está apenas chamando as ferramentas de geoprocessamento ou está fazendo uma quantidade significativa de análise numérica no Python? No primeiro caso, os gargalos provavelmente residem nas ferramentas e o uso de código nativo em seu script não comprará tanto quanto outras soluções alternativas inteligentes. Se for o último, você pode descobrir o que é lento e torná-lo mais rápido com algoritmos melhores, ou possivelmente entorpecidos, ou alguma outra opção, conforme discutido abaixo.

py2exe na verdade, não compila seu código para x86 / x64 nativo, apenas fornece um executável que incorpora seu script como bytecode e fornece uma maneira portátil de distribuí-lo a usuários sem Python em seus sistemas. Falha ao tentar agrupar o arcgisscripting, razão pela qual não funcionou. Na verdade, colocar o py2exe funcionando ainda não fará nada em termos de desempenho.

Eu recomendo fortemente que você primeiro use um criador de perfil para identificar os bits lentos e otimizar a partir daí. Há um conjunto muito bom incorporado ao Python , use o cProfile a longo prazo para encontrar locais em potencial para torná-lo mais rápido. A partir daí, você pode otimizar as seções ausentes em C personalizadas ou, possivelmente, experimentar pequenas porções como módulos .pyx do Cython.

Você pode procurar no Cython a possibilidade de criar todo o script Python como um módulo de extensão de código nativo, mas a Psyco também pode oferecer um aumento de desempenho com uma barreira menor à entrada.


4

Quanto tempo leva o delineamento da bacia hidrográfica, se executado a partir das ferramentas padrão no ArcToolbox em comparação com a versão do script? Se os tempos forem semelhantes, suspeito que não haverá melhorias. Você pode considerar executar processos longos em segundo plano fora do ArcMap.


Esclarei minha pergunta original e espero ainda obter uma resposta afirmativa de sim / não, pois é possível compilar esse código, pois essa resposta não responde à minha pergunta.
turkishgold

2
@ turco Pode não responder diretamente à sua pergunta, mas é uma excelente sugestão. As chances são boas de que seu processo gaste todo o tempo no delineamento, portanto, nenhuma quantidade de ajustes no código ajudará consideravelmente. No entanto, reconsiderar o algoritmo pode fazer uma enorme diferença. Portanto, uma das primeiras coisas que você deseja fazer é criar um perfil da execução atual para ver se você está desperdiçando seu tempo com essa abordagem de compilação.
whuber

1
Eu concordo com @ Dan e @ whuber. Eu acho que fazer uma análise mais profunda (ou seja, benchmarking e criação de perfil) trará uma percepção muito melhor para melhorias de desempenho do que apenas uma abordagem de compilação de força bruta.
Jason Scheirer

4

Não use um banco de dados geográfico pessoal sem um bom motivo. Em nossa experiência, eles são consistentemente muito mais lentos que todas as outras formas de armazenamento de dados esri ( ref ). Embora eu tenha lido um relatório aqui no GIS.se que viu mais rápido que o arquivo gdb.

Quando o fluxo de trabalho consiste em muitas iterações pequenas, a chamada para criar o geoprocessador e verificar uma licença geralmente é a parte mais cara do uso do python. Portanto, fazer o máximo que puder na frente ou atrás gp = ...(ou import arcpyna v10) é uma técnica que eu uso muito.

No que diz respeito à compilação, esta citação diz o melhor:

Vale a pena notar que, enquanto a execução de um script [python] compilado tem um tempo de inicialização mais rápido (como não precisa ser compilado), não é executada mais rapidamente.

Mark Cederholm tem uma apresentação sobre o uso do ArcObjects no Python com algumas estatísticas sobre operações de shapecopy (slide # 4). Python não se sai muito bem, rodando com 32% do que pode ser alcançado com C ++ (o VBA foi de 92%, o VB & C # com 48%). Não corra e grite rápido demais, pois muitas das ferramentas de geoprocessamento são scripts python (pesquise c: \ arquivos de programas \ arcgis \ para '* .py').

Como muitos disseram em outros locais, com o python, o tempo gasto tentando otimizar o desempenho compilando ou gravando uma função principal C ou C ++ geralmente diminui os ganhos reais de desempenho (possivelmente) obtidos em tempo de execução. Muitos dizem que o principal benefício do Python é otimizar e melhorar o tempo do desenvolvedor ; a atenção humana é muito mais valiosa e cara do que o tempo de processamento da máquina.


1
Sim em todos os aspectos. Para meu dinheiro, o uso ideal do tempo do desenvolvedor é fazer o protótipo * em Python, referência, descer para C / C ++ para otimizar gargalos. * Eu digo protótipo, mas sei 95% das vezes que o 'protótipo' vai entrar em produção.
Jason Scheirer

Ótimos comentários e obrigado pelos links do ArcObjects em Python. Eu acho que escrever em um GDB se beneficia de uma perspectiva de gerenciamento de dados versus arquivo de forma (restrições da tabela de atributos em arquivos de formato versus classes de recursos, representação de geometria, práticas gerais de gerenciamento de dados etc.), além de coisas que você pode fazer com muito mais facilidade e limpeza. um ambiente de acesso versus lidar com arquivos DBF. Então, basicamente, uma troca de custo-benefício com o que você está fazendo e o que terá a ver com os dados de saída. O meio termo de rasters fora do GDB e tudo o mais no GDB parece estar funcionando.
precisa saber é o seguinte

1

Você não pode compilar código python em código de máquina. Quando executado pela primeira vez, é compilado para 'bytecode', um idioma intermediário (que cria arquivos pyc)

py2exe agrupa os arquivos DLL exigidos pelo intérprete e quaisquer arquivos python / arquivos externos necessários em um executável. Não é compilado - o tempo de execução não deve ser muito diferente.

É possível fazer o código Python rodar muito rápido, usando uma combinação de diferentes técnicas.

A primeira coisa que você deve fazer é criar um perfil do seu código para encontrar os gargalos. Uma vez encontrado, geralmente uso este processo:

  • Elimine os loops 'for' usando matrizes numpy ou a função map (). Isso basicamente empurra o loop para C.
  • Investigue melhores implementações do algoritmo (isso ocorre simultaneamente com o acima). Coisas como reduzir o número de operações de E / S, garantindo que os dados sejam acessados ​​/ armazenados em blocos contíguos.
  • Intérpretes 'truques', como evitar pesquisas caras nos loops, evitar blocos 'if' nos loops (use 'try')
  • Crie um perfil novamente
  • Se ainda estiver muito lento, tente inserir partes críticas no C usando o Cython (ou escrevendo diretamente em C, criando uma dll e usando ctypes para chamá-lo)
  • Perfil novamente
  • Se ainda estiver muito lento, observe a computação paralela ou GPU (biblioteca de multiprocessamento, pyCUDA, ParallelPython etc.)

0

Se você importar um script python de outro local, ele gera um arquivo .pyc. Portanto, uma maneira fácil de testar se a compilação faz diferença seria transformar seu script em uma função (por exemplo, main ()). Se você salvar esse script example.py, crie outro arquivo com as seguintes linhas:

import example
example.main() # call your script(s)

Se você executa o tempo de dentro do script e quando é importado, talvez possa ver qual é a diferença. Esta é uma maneira de baixa tecnologia de fazê-lo.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.