Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
Olá gente,
Tenho que ler um arquivo txt e inlluir no banco.
Posso escolher dois formatos para o aquivo, ou seja; arquivo tabulado ou arquivo separador por ( ; )
Com o arquivo tabulado tenho que trabalhar com substr para pegar os valores.
No outro irei rabalhar com explode.
O que seria mais rápido(substr ou explode)?
flws...
Sem conhecer o seu arquivo de texto é menos fácil (porque não é difícil) imaginar em que cenário você se encontra. Mas pelo texto posso imaginar que no mínimo sejam pares chave;valor, um por linha.
A performance de uma aplicação está diretamente relacionada com a complexidade do código, com o volume de dados a processar e com o hardware do servidor.
E com complexidade não me refiro unicamente se você suprimiu erros, se programa proceduralmente ou Orientado a Objetos, mas também às escolhas das funções do PHP que você faz.
E é aí que entra a questão.
Veja:
<?php
$start = microtime( true );
$file = file( 'file.txt' );
$data = array();
foreach( $file as $lines ) {
$text = substr( $lines, 0, strpos( $lines, ';' ) );
$value = substr( $lines, ( strlen( $text ) + 1 ) );
$data[ $text ] = $value;
}
var_dump( $data, microtime( true ) - $start );
Aqui pra mim rodou de 0.0003 a 0.0007 segundos. Mas usei um arquivo pequeno, com apenas cinco entradas.
Já uma modificação com explode():
<?php
$start = microtime( true );
$file = file( 'file.txt' );
$data = array();
foreach( $file as $lines ) {
list( $text, $value ) = explode( ';', $lines );
$data[ $text ] = $value;
}
var_dump( $data, microtime( true ) - $start );
Rodou 99% das vezes a 0.0002.
Essa diferença se deu pelo simples fato no primeiro caso serem necessárias três invocações de funções que, mesmo operando sobre strings simples, têm seus pesos somados.
Já na segunda versão, você informa o dado de entrada e informa à função para separá-las pelo caractere em questão. E pronto! Sem sobrecarga, sem cálculos matemáticos, tudo de forma simples.
Isso que eu ainda usei um list() que poderia ter sido evitado, mas eu su fresco. :P
Mas o mais importante na escolha de um método de trabalho de um código é saber qual função utilizar de acordo com o objetivo.
Sua meta é separar as informações para inserir no banco. Para separar informações você normalmente utilizaria split(), mas você conhece o caractere em questão e o próprio manual de recomenda a usar explode() para isso.
Ao optar por substr() você até consegue fazer, mas você precisa de um reforço feito com strpos().
E eu ainda usei um formato conhecido de dado de entrada pois o correto mesmo seria verificar se strpos() não estaria retornando um FALSE, gerando ainda mais peso para o código.
E não se iluda com os contadores em microtime() pois o peso do próprio microtime() mais a operação de subtração estão sendo considerados no tempo final.
Prefira o Apache Benchmark para isso, é gratuito e vem com o Apache do seu servidor.
Prefira o Apache Benchmark para isso, é gratuito e vem com o Apache do seu servidor.
xdebug vem com profiler :D
xdebug vem com profiler :D
Eu acho o AB mais rápido pra esse tipo de dúvida ou curiosidade.
hum... com o formato csv, vc consegue inserir direto no banco, sem precisar escrever nada em php para ler isso. (desde q o arquivo esteja na mesma ordem das tuas colunas)
acho "assim" mais rápido do que qualquer coisa.
Isto não importa, não vai alterar muito de 1 milissegundo para 2, o mais importante é a legibilidade, não vicie em performance.
“Otimização prematura é a raiz de todos os males”. - Donald Knuth
Não quer dizer que não deve haver otimizações, mas não desse tipo, faça cache em banco, otimize imagens, contudo não acabe com seu código. explode é mais legível, logo é o melhor. O problema é se vc perdesse performance em demasia, mas não é o caso.
Olá gente,
Primeiramente quero agradecer peals opniões.
Realizei 3 testes com o mesmo arquivo, 546 linhas:
com substr e strpos
foreach( $file as $linhas )
{
$CD_RESIDUO = substr( $linha, 0, strpos( $linha, ';' ) );
$NM_RESIDUO = substr( $linha, ( strlen( $text ) + 1 ) );
$SUN_MEDIDA = substr( $linha, ( strlen( $NM_RESIDUO ) + 1 ) );
$arrayDados = array('CD_RESIDUO' => $CD_RESIDUO,
'NM_RESIDUO' => $this->limpa($NM_RESIDUO),
'SG_UNIDADE_MEDIDA' => $SUN_MEDIDA);
}com explode:
foreach( $file as $linhas )
{
$dados_linha = explode( ';', $linha );
$arrayDados = array('CD_RESIDUO' => $dados_linha['0'],
'NM_RESIDUO' => $this->limpa($dados_linha['1']),
'SG_UNIDADE_MEDIDA' => $dados_linha['2']);
}com list e explode:
foreach( $file as $linhas )
{
list( $CD_RESIDUO, $NM_RESIDUO, $UN_MEDIDA ) = explode( ';', $linha );
$arrayDados = array('CD_RESIDUO' => $CD_RESIDUO,
'NM_RESIDUO' => $this->limpa($NM_RESIDUO),
'SG_UNIDADE_MEDIDA' => $UN_MEDIDA);
}vou ficar com o ultimo teste.
<?php
$file = fopen('meu_arquivo_csv', 'r');
$fields = array('CD_RESIDUO', 'NM_RESIDUO', 'SG_UNIDADE_MEDIDA');
while (false !== ($row = fgetcsv($file, 0, ';'))) {
$row[1] = $this->limpa($row[1]);
$arrayDados = array_combine($fields, $row);
}
Posso lhe dar uma dica... vc tem como medir o tempo do processo de cada um..
vc simula os dois métodos e roda eles... segue script para lhe dar o tempo
// Script que desejas medir o tempo