Ir para conteúdo
  • Cadastre-se

dev botao

  • Este tópico foi criado há 4423 dias atrás.
  • Talvez seja melhor você criar um NOVO TÓPICO do que postar uma resposta aqui.

Recommended Posts

Postado

Olá pessoal, tudo bem ? Preciso de ajuda, estou tentando eliminar alguns gargalos de velocidade no meu software e gostaria de saber se o uso da sintaxe [[[ with...do ]]] é capaz de acelerar em algo meu software mesmo que o ganho seja pequeno. Por exemplo, considerando no cenário abaixo:

//Cenário 1

TClientDataSet(FindGlobalComponente('frmCliente').FindComponente('cdsCliente')).Append;

TClientDataSet(FindGlobalComponente('frmCliente').FindComponente('cdsCliente')).FieldByName('valor01').asString := '1';

TClientDataSet(FindGlobalComponente('frmCliente').FindComponente('cdsCliente')).FieldByName('valor02').asString := '2';

TClientDataSet(FindGlobalComponente('frmCliente').FindComponente('cdsCliente')).FieldByName('valor03').asString := '3';

...

TClientDataSet(FindGlobalComponente('frmCliente').FindComponente('cdsCliente')).FieldByName('valor99').asString := '99';

TClientDataSet(FindGlobalComponente('frmCliente').FindComponente('cdsCliente')).FieldByName('valor100').asString := '100';

TClientDataSet(FindGlobalComponente('frmCliente').FindComponente('cdsCliente')).Post;

Como podem ver no cenário acima tenho 100 linhas de entrada de instruções entre o Append e o Post, gostaria de substituir pelo cenário abaixo:

//Cenário 2

with TClientDataSet(FindGlobalComponente('frmCliente').FindComponente('cdsCliente')) do

begin

Append;

FieldByName('valor01').asString := '1';

FieldByName('valor02').asString := '2';

FieldByName('valor03').asString := '3';

...

FieldByName('valor99').asString := '99';

FieldByName('valor100').asString := '100';

Post;

end;

Desconsiderando por completo o fato de que o código ficará mais limpo/legível, gostaria de saber se a troca do cenário 1 pelo cenário 2 resultaria em ganhos de velocidade/performance. Alguém já teve alguma EXPERIÊNCIA CONCRETA E VÁLIDA sobre isso ? Alguém poderia comentar algo, acredito que a um tempo atrás já ter lido algo sobre o uso de [[[ with...do ]]] nesse mesmo fórum. Agradeço a todos a atenção...

  • Moderadores
Postado

Vou lhe dar uma pequena sugestão tente abrir e verificar o que faz "FieldByName"

e depois tire as conclusões que nos dois casos vai ser demora sua aplicação


function TDataSet.FieldByName(const FieldName: string): TField;

begin

  Result := FindField(FieldName);

  if Result = nil then DatabaseErrorFmt(SFieldNotFound, [FieldName], Self);

end;

agora descendo mais um pouco

function TDataSet.FindField(const FieldName: string): TField;

begin

  Result := FFields.FindField(FieldName);

  if (Result = nil) and ObjectView then

    Result := FieldList.Find(FieldName);

  if Result = nil then

    Result := FAggFields.FindField(FieldName);

end;

e agora só um ultimo

function TFields.FindField(const FieldName: string): TField;

var

  I: Integer;

begin

  for I := 0 to FList.Count - 1 do

  begin

    Result := FList.Items[I];

    if AnsiCompareText(Result.FFieldName, FieldName) = 0 then Exit;

  end;

  Result := nil;

end;

Imagine quantas interações vão ter que ser feitas só para passar num pequeno trecho de código

Consultor SAC ACBr Juliomar Marchetti
 

Projeto ACBr

skype: juliomar
telegram: juliomar
e-mail: [email protected]
http://www.juliomarmarchetti.com.br
MVP_NewLogo_100x100_Transparent-02.png
 

 

Postado

Acredito que seu maior problema realmente seja a falta de with neste caso, pois eliminará muitos usos de "TClientDataSet(FindGlobalComponente('frmCliente').FindComponente('cdsCliente'))" que é um bucado custoso.

Mas como o juliomar disse, se puder utilizar o componente diretamente seria o ideal, algo como:

with frmCliente do

begin

  cdsCliente.Append;

  cdsClientevalor01.value:= '1';

  cdsClientevalor02.value:= '2';

  cdsClientevalor03.value:= '3';

  ...

  cdsClientevalor99.value:= '99';

  cdsClientevalor100.value:= '100';

  cdsCliente.Post;

end;

- Sou desenvolvedor.

- De que linguagem, delphi? .NET? Java?

- Qualquer uma, sou desenvolvedor.

Postado

Valeu galera, vcs são feras, também já tinha lido algo de negativo (perda de performance) sobre o método FieldByName mas nosso software usando um dicionário de dados cria os Fields dentro dos ClientDataSets em tempo de execução ao abrir os formulários, ou seja, os fields [cdsClientevalor01] não existem quando estou programando no Delphi e sou obrigado a usar [cdsCliente.ieldByName('valor01')] senão o Delphi acusa erro informando que o Field [cdsClientevalor01] não existe. Enfim, vou começar a usar o with...do com mais freqüência na esperança que o desempenho de meu software melhore. E qualquer sugestão ainda é bem vinda, valeu galera !!!

Postado

Valeu galera, vcs são feras, também já tinha lido algo de negativo (perda de performance) sobre o método FieldByName mas nosso software usando um dicionário de dados cria os Fields dentro dos ClientDataSets em tempo de execução ao abrir os formulários, ou seja, os fields [cdsClientevalor01] não existem quando estou programando no Delphi e sou obrigado a usar [cdsCliente.ieldByName('valor01')] senão o Delphi acusa erro informando que o Field [cdsClientevalor01] não existe. Enfim, vou começar a usar o with...do com mais freqüência na esperança que o desempenho de meu software melhore. E qualquer sugestão ainda é bem vinda, valeu galera !!!

Com "with" Sem "with" a performance é a mesma. "ruim".

--
Isaque Pinheiro
Aracruz/ES - Brasil
___________________________________________________________________________
Site Oficial: www.isaquepinheiro.com.br 
Youtube: youtube.com/isaquepinheirooficialbr
Facebook: facebook.com.br/isaquepinheirooficialbr
Instagram: instagram.com/isaquepinheirooficialbr
Linkdin: https://www.linkedin.com/in/isaquepinheirooficialbr

Conheça o Projeto ORMBr Framework for Delphi - https://www.ormbr.com.br

 

  • Consultores
Postado

O uso do with deve ser evitado por dois motivos básicos: pode tornar o código menos legível e pode confundir o compilador no caso de uso de classes com métodos ou propriedades que tenham mesmo nome.

Ainda assim, o with usado no seu código atual vai reduzir as chamadas conforme mencionado, e provavelmente vai agilizar o código.

Mas seria melhor você fazer algo assim:


procedure xxxxxxx
Var
cdsClienteRunTime:TClientDataSet
begin
//....
cdsClienteRunTime := TClientDataSet(FindGlobalComponente('frmCliente').FindComponente('cdsCliente'));
cdsClienteRunTime.Append;
cdsClienteRunTime.FieldByName('valor01').asString := '1';
cdsClienteRunTime.FieldByName('valor02').asString := '2';
cdsClienteRunTime.FieldByName('valor03').asString := '3';
//...
cdsClienteRunTime.FieldByName('valor99').asString := '99';
cdsClienteRunTime.FieldByName('valor100').asString := '100';
cdsClienteRunTime.Post;[/code] Mas a raiz do problema do seu código no primeiro cenário não é a criação dos objetos em RunTime. O problema é a falta de controle sobre essa criação. Por exemplo: Se você criou um objeto frmCliente, você já deveria saber onde ele está e qual é a instância do objeto que o controla. Não deveria ser necessário você usar um método do tipo FindGlobalComponente('frmCliente') para isso. Ou mesmo que fosse necessário, você deveria poder fazer a mesma coisa da ideia do with anterior.
[code]
frmCliente := TfrmCliente(FindGlobalComponente('frmCliente')); //a partir daqui só usar-se-á frmCliente.

Finalmente, sobre o uso do FieldByName no seu segundo cenário.

Exatamente como o Isaque mencionou, com o With ou sem o With será ruim a performance. Isso pois o método FieldByName é lento por natureza. Por isso, sempre que possível é melhor usar o objeto direto. Ou então usar a propriedade Fields do dataset.

Mas há alguns casos que usar FieldByName é realmente necessário e você tem algumas saídas para agilizar as chamadas.

Veja esse link: http://delphi.about.com/od/database/ss/faster-fieldbyname-delphi-database.htm

Esse artigo explica alguns métodos para "acelerar o FieldByName" e você pode escolher o que lhe aplica melhor.

Espero que ajude. :ugeek:

[]'s

Consultor SAC ACBr

Elton
Profissionalize o ACBr na sua empresa, conheça o ACBr Pro.

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.

Um engenheiro de Controle de Qualidade(QA) entra num bar. Pede uma cerveja. Pede zero cervejas.
Pede 99999999 cervejas. Pede -1 cervejas. Pede um jacaré. Pede asdfdhklçkh.
  • 5 semanas depois ...
Postado

O uso do with deve ser evitado por dois motivos básicos: pode tornar o código menos legível e pode confundir o compilador no caso de uso de classes com métodos ou propriedades que tenham mesmo nome.

Ainda assim, o with usado no seu código atual vai reduzir as chamadas conforme mencionado, e provavelmente vai agilizar o código.

Mas seria melhor você fazer algo assim:


procedure xxxxxxx

Var 

  cdsClienteRunTime:TClientDataSet

begin

  //....

  cdsClienteRunTime := TClientDataSet(FindGlobalComponente('frmCliente').FindComponente('cdsCliente'));

  cdsClienteRunTime.Append;

  cdsClienteRunTime.FieldByName('valor01').asString := '1';

  cdsClienteRunTime.FieldByName('valor02').asString := '2';

  cdsClienteRunTime.FieldByName('valor03').asString := '3';

  //...

  cdsClienteRunTime.FieldByName('valor99').asString := '99';

  cdsClienteRunTime.FieldByName('valor100').asString := '100';

  cdsClienteRunTime.Post;
Mas a raiz do problema do seu código no primeiro cenário não é a criação dos objetos em RunTime. O problema é a falta de controle sobre essa criação. Por exemplo: Se você criou um objeto frmCliente, você já deveria saber onde ele está e qual é a instância do objeto que o controla. Não deveria ser necessário você usar um método do tipo FindGlobalComponente('frmCliente') para isso. Ou mesmo que fosse necessário, você deveria poder fazer a mesma coisa da ideia do with anterior.

frmCliente :=  TfrmCliente(FindGlobalComponente('frmCliente')); //a partir daqui só usar-se-á frmCliente.

Finalmente, sobre o uso do FieldByName no seu segundo cenário.

Exatamente como o Isaque mencionou, com o With ou sem o With será ruim a performance. Isso pois o método FieldByName é lento por natureza. Por isso, sempre que possível é melhor usar o objeto direto. Ou então usar a propriedade Fields do dataset.

Mas há alguns casos que usar FieldByName é realmente necessário e você tem algumas saídas para agilizar as chamadas.

Veja esse link: http://delphi.about.com/od/database/ss/faster-fieldbyname-delphi-database.htm

Esse artigo explica alguns métodos para "acelerar o FieldByName" e você pode escolher o que lhe aplica melhor.

Espero que ajude. :ugeek:

Amigo, obrigado pela dica acima, já coloquei a página nos favoritos e estou lendo-a atentamente, vlw mesmo !!!

  • Este tópico foi criado há 4423 dias atrás.
  • Talvez seja melhor você criar um NOVO TÓPICO do que postar uma resposta aqui.

Crie uma conta ou entre para comentar

Você precisar ser um membro para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar Agora
×
×
  • Criar Novo...

Informação Importante

Colocamos cookies em seu dispositivo para ajudar a tornar este site melhor. Você pode ajustar suas configurações de cookies, caso contrário, assumiremos que você está bem para continuar.

The popup will be closed in 10 segundos...