Embora essa pergunta já tenha sido respondida, pensei em dar um toque de dois centavos.
AVISO LEGAL : Eu trabalhei para a ESRI na equipe do GeoDatabase por alguns anos e fiquei encarregado de manter várias partes do código do GeoDatabase (controle de versão, cursores, edições de edição, histórico, classes de relacionamento etc.).
Eu acho que a maior fonte de problemas de desempenho com o código ESRI não é entender as implicações do uso de objetos diferentes, particularmente os "pequenos" detalhes das várias abstrações do GeoDatabase! Com muita frequência, a conversa muda para o idioma usado como culpado dos problemas de desempenho. Em alguns casos, pode ser. Mas não o tempo todo. Vamos começar com a discussão do idioma e voltar ao trabalho.
1.- A linguagem de programação que você escolhe só importa quando você está fazendo algo que é complicado, em um loop apertado. Na maioria das vezes, esse não é o caso.
O grande elefante na sala é que, no centro de todo o código ESRI, você tem ArcObjects - e o ArcObjects é escrito em C ++ usando COM . Há um custo para se comunicar com esse código. Isso é verdade para C #, VB.NET, python ou qualquer outra coisa que você esteja usando.
Você paga um preço na inicialização desse código. Isso pode ser um custo insignificante se você fizer isso apenas uma vez.
Você paga um preço por cada tempo subsequente em que interagir com o ArcObjects.
Pessoalmente, costumo escrever código para meus clientes em C #, porque é fácil e rápido o suficiente. No entanto, toda vez que eu quero mover dados ou fazer algum processamento para grandes quantidades de dados já implementadas no Geoprocessamento, eu apenas inicializo o subsistema de script e passo meus parâmetros. Por quê?
- Já está implementado. Então, por que reinventar a roda?
- Na verdade, pode ser mais rápido . "Mais rápido do que escrever em C #?" Sim! Se eu implemente, digamos, o carregamento manual de dados, significa que pago o preço da alternância de contexto .NET em um loop restrito. Todo GetValue, Insert, ShapeCopy tem um custo. Se eu fizer uma chamada no GP, todo o processo de carregamento de dados ocorrerá na implementação real do GP - em C ++ no ambiente COM. Não pago o preço pela alternância de contexto porque não há - e, portanto, é mais rápido.
Ah, sim, então a solução é usar muitas funções de geoprocessamento. Na verdade, você tem que ter cuidado.
2. GP é uma caixa preta que copia dados (potencialmente desnecessariamente) em torno de
É uma espada de dois gumes. É uma caixa preta que faz mágica internamente e cospe resultados - mas esses resultados costumam ser duplicados. 100.000 linhas podem ser facilmente convertidas em 1.000.000 de linhas no disco após a execução dos dados em 9 funções diferentes. Usar apenas funções GP é como criar um modelo linear GP, e bem ...
3. Encadear muitas funções GP para grandes conjuntos de dados é altamente ineficiente. Um modelo de GP é (potencialmente) equivalente a executar uma consulta de uma maneira realmente muito muito burra
Agora não me interpretem mal. Eu amo os GP Models - isso me impede de escrever código o tempo todo. Mas também estou ciente de que não é a maneira mais eficiente de processar grandes conjuntos de dados.
Você já ouviu falar de um planejador de consultas ? Seu trabalho é examinar a instrução SQL que você deseja executar, gerar um plano de execução na forma de um gráfico direcionado que se parece muito com um Modelo GP , examinar as estatísticas armazenadas no banco de dados e escolher a opção mais adequada. ordem ideal para executá-los . O GP apenas os executa na ordem em que você coloca as coisas, porque não possui estatísticas para fazer algo de maneira mais inteligente - você é o planejador de consultas . E adivinha? A ordem em que você executa as coisas depende muito do seu conjunto de dados. A ordem em que você executa as coisas pode fazer a diferença entre dias e segundos e cabe a você decidir.
"Ótimo" você diz, eu não vou escrever as coisas sozinho e ter cuidado com a forma como escrevo as coisas. Mas você entende abstrações do GeoDatabase?
4.Não entender as abstrações do GeoDatabase podem mordê-lo facilmente
Em vez de apontar tudo o que pode causar um problema, deixe-me apontar alguns erros comuns que vejo o tempo todo e algumas recomendações.
- Compreendendo a diferença entre os cursores Verdadeiro / Falso para Reciclagem . Esse pequeno sinalizador definido como verdadeiro pode tornar as ordens de execução de magnitude mais rápidas.
- Coloque sua tabela no LoadOnlyMode para carregar dados. Por que atualizar o índice em cada inserção?
- Entenda que, embora o IWorkspaceEdit :: StartEditing pareça o mesmo em todos os espaços de trabalho, eles são bestas muito diferentes em todas as fontes de dados. Em um Enterprise GDB, você pode ter controle de versão ou suporte para transações. Nos shapefiles, ele terá que ser implementado de uma maneira muito diferente. Como você implementaria Desfazer / Refazer? Você precisa ativá-lo (sim, isso pode fazer a diferença no uso da memória).
- A diferença entre operações em lote ou operações de linha única. Caso em questão GetRow vs GetRows - esta é a diferença entre fazer uma consulta para obter uma linha ou fazer uma consulta para buscar várias linhas. Um loop apertado com uma chamada para GetRow significa desempenho horrível e é o culpado nº 1 de problemas de desempenho
- Use UpdateSearchedRows
- Entenda a diferença entre CreateRow e CreateRowBuffer . Enorme diferença no tempo de execução da inserção.
- Entenda que IRow :: Store e IFeature :: Store disparam operações polimórficas super pesadas . Esta é provavelmente a razão # 2 culpada de desempenho realmente lento. Ele não salva apenas a linha, este é o método que garante que sua rede geométrica esteja correta, que o ArcMap Editor seja notificado de que uma linha foi alterada, que notifica todas as classes de relacionamento que têm algo a ver com essa linha validada para tornar verifique se a cardinalidade é válida etc. Você não deve inserir novas linhas com isso, deve usar um InsertCursor !
- Deseja (precisa) fazer essas inserções em uma EditSession? Faz uma enorme diferença se você faz ou não. Algumas operações exigem isso (e tornam as coisas mais lentas), mas quando você não precisar, pule os recursos de desfazer / refazer.
- Cursores são recursos caros. Depois de ter um identificador para um, você tem a garantia de que terá Consistência e Isolamento e que terá um custo.
- Coloque em cache outros recursos, como conexões com o banco de dados (não crie e destrua sua referência da Área de Trabalho) e identificadores de Tabela (toda vez que você abrir ou fechar um - várias tabelas de metadados precisam ser lidas).
- Colocar o FeatureClasses dentro ou fora de um FeatureDataset faz uma enorme diferença no desempenho. É não entende como um recurso organizacional!
5.E por último e não menos importante ...
Entenda a diferença entre operações de ligação de E / S e de CPU
Sinceramente, pensei em expandir mais cada um desses itens e talvez fazer uma série de entradas de blog que abrangem todos esses tópicos, mas a lista de pendências do meu calendário me deu um tapa na cara e começou a gritar comigo.
Meus dois centavos.