Bomba Relógio-Memória ABAP – Procedural x OO

Este post é em homenagem e agradecimento ao nosso leitor Gabriel Tognoli, que nos deu um puxão de orelha totalmente merecido por não estarmos atualizando o blog com a frequencia devida. Gabriel, obrigado pelo incentivo – espero que este post lhe ajude tanto quanto os outros.

Há muitos contestamentos sobre a diferença de desempenho entre códigos procedurais e orientado a objetos. O principal argumento que acusa um menor desempenho de programas orientado a objetos é a existência do Garbage Collector, que é responsável por identificar objetos que não possuem referência e exterminá-los da memória. E claro, essa varredura na memória tem um custo computacional inexistente em programas procedurais.

Mas e quanto ao espaço na memória ocupado por objetos? Será que é um espaço considerável? Essa é uma dúvida que tive e que resultou num teste que chamo de “Bomba Relógio” e que gostaria de compartilhar.

A ideia do teste é o mais simples possível. Fazer um programa que preencha uma tabela interna “infinitamente” até que a memória acabe e ocorra um dump. A tabela interna varia de acordo com a bomba a ser testada. Na descrição do dump, é possível recolher a informação de quantos registros foram inseridos na tabela interna usando a variável de sistema SY-TABIX. Essa variável mantém a informação de quantas vezes um LOOP foi executado.

 

Bomba Procedural

A bomba procedural pode ser pensada como um programa “Bye World” (versão “Hello World” do programador sem medo). Uma tabela interna de strings é preenchida sempre com um ‘X’ até o dump ser gerado. Dê só uma olhada:

Bomba OO Simples

A bomba orientada a objetos em sua verão simples, merece um destaque maior. Nela, um objeto da classe local lcl_data contém apenas um atributo, também do tipo string. O programa desta vez cria um novo objeto para interação do LOOP infinito, define o atributo da classe também com ‘X’ e adiciona a referência do objeto recém criado em uma tabela interna própria para tal. Confira no código abaixo. 

 

Bomba OO Singleton

A bomba orientada objetos na versão singleton é um pouco mais simples. Podemos pensar nela como a mais simples transformação da versão procedural. Nesta versão, a tabela interna de strings foi encapsulada dentro de uma classe. Assim, a tabela interna se torna um atributo da classe local lcl_data. O programa cria apenas um objeto (antes do LOOP) e após isso adiciona infinitamente novas linhas preenchidas novamente com ‘X’. O nome “singleton” não quer dizer que usou-se o design pattern aqui, ele é simplesmente um nome intuitivo para mencionar que apenas um objeto foi instanciado. Eis o código da versão:

Arquivos .nugg e PDF dos Dumps

Nos links a seguir você pode baixar o arquivo .nugg que contém os três programas criados para a realização do teste  (se você não sabe que arquivo é esse, veja o post do SAP Link) e arquivos PDFs dos dumps ocorridos em cada um dos programas.

Importante: O arquivo acima irá ser baixado com a extensão .txt. Substitua a extensão para .nugg para fazer o arquivo ser reconhecido pelo seu SAP Link.

Comparação das Bombas

Podemos perceber que apesar de funcionalmente os programas serem idênticos, o dump gerado em cada situação nem sempre é o mesmo.  Esses são os únicos exemplos de que o funcionamento de um programa deveria ser a falha dos mesmos. =)

No caso das bombas procedural e singleton, o runtime error é o mesmo:

“SYSTEM NO ROLL – Unable to fulfill request for [memory size] bytes of memory space.”

Ou seja, a memória disponível para a sessão esgotou-se. No caso da versão OO simples, na qual múltiplas intâncias são criadas, o erro é outro:

“STORAGE PARAMETERS WRONG SET – The system is configured incorrectly”

Isso é bem mentira, como é fácil de perceber – nada está configurado errado. De qualquer modo, vale a pena entrar na sessão “What happened?” do dump deste programa:

The program had already requested 799522256 bytes from the operating system with ‘malloc‘ when the operating system reported after a further memory request that there was no more memory space available.

Para quem já teve o desprazer de trabalhar com C, sabe que malloc é o comando que se dá para reservar um espaço de memória. Logo no fundo, o erro é o mesmo.

Consolidando todas as informações pertinentes dos dumps para todas as bombas, temos a seguinte tabela:

Conclusão

Notavelmente, as versões procedural e singleton se equiparam no que tange ao consumo de memória. A versão “simples” acaba tendo um resultado bem aquém do imaginado – confesso que não esperava por isso.

A partir destes números, é fato que há um gasto de memória considerável para armazenar informações sobre instâncias. Não é a intenção deste post discutir as áreas reservadas de memória para cada sessão processo de trabalho. Nos dumps da versão procedural e singleton, há uma breve explicação sobre estas áreas.

O que quero destacar aqui é a diferença ocorrida apenas pela utilização de uma granularidade maior na versão OO simples. Ao invés de encapsularmos a tabela interna inteira, encapsulamos as work areas inseridas nela. Realmente isso revelou um resultado espantador.

Todavia, como destacado no começo do post, a versão OO que mais se aproxima da procedural é a singleton, por isso através deste teste não há mais desculpas para não usar Orientação a Objetos . 😉

Melhorando os Testes

Vimos aqui um simples teste de memória. Que tal pensar em um teste de desempenho? Será que essas versões diferem consideravelmente em sua velocidade de execução?

Para fazer essa medição, é uma boa ideia evitar os dumps, para ser justo. Substitua o LOOP infinito por um LOOP consideravelmente grande (~ 3 milhões de vezes é um bom número no meu caso já que a pior versão suportou tal quantidade de dados). Cheque se há discrepância na capacidade de memória do seu minisap (não acho boa ideia tentar isso no trabalho). A outra dica é usar o comando GET TIME STAMP. F1 nele caso você não o conheça. 😉

Abraços a todos e boa Páscoa! Especialmente a o nosso leitor homenageado, Gabriel Tognoli.

 

Fábio Pagoti

Formado em Sistemas de Informação pela Universidade de São Paulo. Comecei no mundo da programação com Java mas logo caí no mundo ABAP. Estagiei na Nestlé por 2 anos e foi lá onde conheci o Furlan. Depois de efetivado fui morar no Canadá por 1 ano onde pude aprender a área de testes em desenvolvimento de software. Hoje sou consultor e instrutor ABAP, amante de projetos Open Source, Wordpress, Data Mining e da esfera SAP. Siga-me no twitter: @fabiopagoti

Você pode gostar...

1 Resultado

  1. março 26, 2012

    […] mais memória do que o seu equivalente em procedural, para uma boa ilustração disso, veja o post onde o Fábio fez uma comparação de consumo de memória entre uma tabela interna e os mesmos […]