sábado, 5 de dezembro de 2009

Genexus é lento?

Muitas pessoas, ao ouvirem a respeito de Genexus, argumentam que a ferramenta é lenta no acesso ao banco de dados, e portanto, não é interessante. Meu argumento sempre foi o de que por facilitar a manutenção, a ferramenta poderia até ser um pouco mais lenta no acesso à base, mas que a longo prazoo sistema teria menor custo.

Bom, me deparei com uma situação que de fato trazia grande desconforto na montagem de uma determinada interface, porque levava segundos até ser apresentada para o usuário, em um sistema Web, e o pior era que essa interface tinha que ser reconstruída a cada clique do usuário na tela.

Isso me levou a descer um pouco mais nas profundezas do gerador, e tentar entender o porque do acesso á base deixava a interface tão lenta. No final das contas o acesso que tinha que fazer era a uma tabela com alguns joins inner e outer, mas que no final retornava em torno de 150 registros. Ou seja, nada muito complexo a ponto de justificar segundos para a montagem da interface.

Primeiramente descobri que o gerador inclui as queries SQL no próprio código gerado em C#, portanto podem ser estudadas e até mesmo testadas externamente, basta um CTRL + C e CTRL + V, no SQL Server, substituindo evidentemente os parâmetros da query, isso pode ser interessante, porque no final das contas se fosse programado manualmente a query gerada não seria muito diferente da que o Genexus cria. Portanto, alguma coisa não estava muito evidente, porque se a query era a mesma gerada manualmente, porque a interface estava lenta.

Eis um exemplo da query do Genexus no código:

new GeneXus.Data.NTier.ADO.CursorDef("T00012", "SELECT [CustomerId], [CustomerName], [CustomerAddress], [CustomerGender] FROM [Customer] WITH (UPDLOCK) WHERE [CustomerId] = @CustomerId ",true, GxErrorMask.GX_NOMASK, false, this,prmT00012,1,0,true,false )

Em seguida reprogramei o acesso a base de dados, desta vez programando a query manualmente na própria ferramenta, ou seja, em código nativo C#. Esperava que com isso o resultado fosse melhorar significativamente, mesmo porque deu muito trabalho para programar na mão o que o Genexus fazia apenas colocando um Grid e os atributos, e o resultado infelizmente não ajudou muito, continuava lento.

Enfim, não era o acesso que estava complicando, no meu caso, e sim a montagem da interface gráfica. Observando atentamente o que havia feito cheguei a conclusão que a interface possuía:

1. Um grid Freestyle com muitas variáveis (nenhum atributo) porque a programação do acesso foi totalmente manual
2. Muito código na área de eventos, e muitos repetidos, porque era necessário muitos cálculos e navegação nos dados recuperados da base.
3. Armazenamento de informações na própria interface gráfica (na prática estava colocando uma SDT do tipo collection na interface para recuperação dos flags gerados pelo usuário)

Recomendação

Após muita programação e reprogramação da interface, cheguei a algumas conclusões interessantes, e que acho que podem te ajudar em problemas semelhantes.

Em primeiro lugar deixe a database para o Genexus mesmo, não vai melhorar muita coisa, talvez alguns milisegundos, mas o argumento da manutenção continua a ser o mais importante, porque uma coisa é resolver o problema para entregar o programa e outra é resolver problemas após a entrega, que no meu ponto de vista é pior.

Outra coisa, fique atento ao uso de variáveis na interface, pois são mais lentas que atributos, evitando colocar muitas no Grid. Cheguei à conclusão que é melhor uma única com todos os valores em uma string do que várias com os valores separadinhos na interface. Mesmo que isso signifique que se tenha que separa os valores (SPLIT) para as utilizar.

Não siga a lógica do armazenamento dos valores na interface para uso na carga POST da interface (aquela realizada por uma ação do usuário), mesmo porque o Genexus vai executar tudo novamente, o START, a carga do grid, a leitura da interface, portanto, é mais fácil armazenar na base o que o usuário realizou e em seguida recalcular tudo do que guardar na interface o que o usuário fez.

A Interface

Após falar tanto, acho que voce deve ter ficado um pouco curioso a respeito da tal interface gráfica complexa, então vou deixar uma imagem aqui para que voce durma esta noite.

Não cabe aqui discutir muito a respeito da operação (matricula de alunos), mas trata-se de uma interface baseada em clicks nas caixinhas, onde a cor azul = selecionado, amarelo = escolhido pelo usuário e vermelho = bloqueado devido à escolha. A cada confirmação o usuário escolhe o recurso e a interface deve ser reconstruída.
Esta interface roda na Web, atualmente, quase com o mesmo desempenho de uma interface Windows local.
Conclusão

Talvez esse artigo sirva para os programadores mais experientes, e que tenham grandes desafios em interfaces complexas, e não para os iniciantes, mas posso dizer com certeza que Genexus é uma ferramenta poderosa no acesso á base e não deixa nada a desejar à programação tradicional e manual. Se dominada, permitirá a você fazer grandes coisas com pouco esforço.