falcao544 11 Denunciar post Postado Julho 12, 2012 A minha dúvida é essa mesmo, porque usar sprintf? Vejo muitas pessoas usando o sprintf, mas não entendo o porque! Já li sobre o sprintf no php.net, mas mesmo assim não vi nada que justificasse tantas pessoas usarem! Obrigado! Compartilhar este post Link para o post Compartilhar em outros sites
Andrey Knupp Vital 136 Denunciar post Postado Julho 12, 2012 Porque é mais claro, já faz o casting ... Compartilhar este post Link para o post Compartilhar em outros sites
falcao544 11 Denunciar post Postado Julho 13, 2012 Casting seria a conversão do tipo do dado para outro tipo? Ex: string para array? E é só isso? Compartilhar este post Link para o post Compartilhar em outros sites
Andrey Knupp Vital 136 Denunciar post Postado Julho 13, 2012 Mais ou menos, como o PHP não tem uma tipagem muito forte, igual a do Java, C++ ... um exemplo: $x1 = '10' ; // string $x2 = 10 ; // integer $x = ($x1 + $x2); // 20 Se você mandar '10', e sua função no C++ esperar um int, ou no Java, você terá um erro, lá você teria que fazer esse cast. No php, independente de ser integer/string, a soma será feita. Em java: public class PrimitiveTypes { public static void main(String[] args) { int x1 = 10 ; String x2 = "10"; int x = x1 + x2 ; System.out.println(x); } } Resulta em: Exception in thread "main" java.lang.RuntimeException: Uncompilable source code - incompatible types required: int Não vou dar o exemplo em C++ porque estou sem o compiler aqui. Compartilhar este post Link para o post Compartilhar em outros sites
Henrique Barcelos 290 Denunciar post Postado Julho 13, 2012 Às vezes é melhor do que ficar concatenando variáveis, quando se tem uma sentença longa composta de várias variáveis. $t = 'Olá, meu nome é' . $nome . ', tenho ' . $idade . ' anos e sou ' . $profissao; ou $t = sprintf('Olá, meu nome é %s, tenho %d anos e sou %s', $nome, $idade, $profissao); Normalmente, quem teve um pouco de contato com C e os *printf, *scanf da vida prefere esse tipo de sintaxe. Eu uso bastante, odeio ter que ficar abrindo e fechando aspas pra concatenar strings e não uso as aspas duplas por questões de performance: $t = "Olá, meu nome é {$nome}, tenho {$idade} anos e sou {$profissao}"; O PHP vai ler toooooda essa string aí procurando por variáveis. Quando usamos aspas simples, ele não procura variáveis dentro da string, melhorando o desempenho. Edit: essa questão do desempenho foi o próprio Rasmus Lerdorf que apontou no seu blog pessoal. Entretanto, aqui diz o contrário: http://judebert.com/progress/archives/204-PHP-String-Formatting-Performance.html Compartilhar este post Link para o post Compartilhar em outros sites
Henrique Barcelos 290 Denunciar post Postado Julho 13, 2012 Fiz alguns testes aqui, obtive outras medidas: $ php test.php 100 1000 Saída: Média de 100 repetições para 1000 concatenações sprintf: 0.001989 s single-quote: 0.000702 s double-quote: 0.000783 s heredoc: 0.000813 s Executei várias vezes os testes. Usando single-quote ou double-quote e heredoc, os valores são bem parecidos e tendem ao mesmo ponto a medida que eu aumento o número de concatenações. O sprintf vem sempre na lanterna. O benchmark usado foi esse: <?php set_time_limit(0); $nome = 'Henrique'; $idade = '21'; $profissao = 'Estudante'; $times = array(); $phrase; $rep = isset($argv[1]) ? $argv[1] : 1000; $cat = isset($argv[2]) ? $argv[2] : 1000; printf("Média de %d repetições para %d concatenações\n", $rep, $cat); for($i = 0; $i < $rep; $i++) { $ini = microtime(true); for($j = 0; $j < $cat; $j++) { $phrase = sprintf('Olá, meu nome é %s, tenho %d anos e sou %s', $nome, $idade, $profissao); } $end = microtime(true); $times[] = $end - $ini; } printf("sprintf: %f s\n", array_sum($times)/$rep); $times = array(); for($i = 0; $i < $rep; $i++) { $ini = microtime(true); for($j = 0; $j < $cat; $j++) { $phrase = 'Olá, meu nome é '. $nome . ', tenho ' . $idade . ' anos e sou ' . $profissao; } $end = microtime(true); $times[] = $end - $ini; } printf("single-quote: %f s\n", array_sum($times)/$rep); $times = array(); for($i = 0; $i < $rep; $i++) { $ini = microtime(true); for($j = 0; $j < $cat; $j++) { $phrase = "Olá, meu nome é ${nome}, tenho ${idade} anos e sou ${profissao}"; } $end = microtime(true); $times[] = $end - $ini; } printf("double-quote: %f s\n", array_sum($times)/$rep); $times = array(); for($i = 0; $i < $rep; $i++) { $ini = microtime(true); for($j = 0; $j < $cat; $j++) { $phrase = <<<HEREDOC Olá, meu nome é ${nome}, tenho ${idade} anos e sou ${profissao} HEREDOC; } $end = microtime(true); $times[] = $end - $ini; } printf("heredoc: %f s\n", array_sum($times)/$rep); Compartilhar este post Link para o post Compartilhar em outros sites
Bruno Augusto 417 Denunciar post Postado Julho 13, 2012 Seu teste está correto Henrique. A "precedência de performance" é essa mesma: Single Quotes >> Double Quotes >> Heredoc >> (v)(s)printf (e cia) Usar (v)(s)printf não é o melhor em termos de performance pois você está invocando uma função, que por si só, já tem seu "custo". Além disso,(v)(s)printf tem de analisar toda a string, verificar quantos placeholders foram definidos, verificar se foram informados argumentos suficientes, se são do tipo certo e ainda fazer a conversão. Mas, pelo menos pra mim, o benefício proporcionado é tão grande que ignoro veementemente as outras formas de composição de string. :closedeyes: Compartilhar este post Link para o post Compartilhar em outros sites
Gabriel Heming 766 Denunciar post Postado Julho 13, 2012 @Henrique Barcelos Só uma consideração. No manual do PHP, há um teste de performance sobre apóstrofo e aspas duplas. Ele foi feito por um usuário na parte de códigos. E acredite, aspas duplas se demonstrou mais performático. A diferença foi mínima, mas em todos os testes feitos, foi superior. Segue o teste, eu adaptei com sprintf e suas variações. Código: <?php$var = 1; for( $x=0; $x < 21; $x++ ) { echo '<br /><br />var = int( '.$var.' )<br />'; $tempoInicial = microtime(true); for( $i=0; $i<100001; $i++ ) { $string = " {$var} {$var} {$var} {$var} {$var} {$var} {$var} {$var} {$var} {$var} {$var} {$var} {$var} {$var} {$var}"; unset( $string ); } $tempoFinal = microtime(true); echo '<br />One string with 15 $vars was set using one concat 100000 times and took '.number_format(($tempoFinal - $tempoInicial), 3, ',', '.').' seconds to execute '; $tempoInicial = microtime(true); for( $i=0; $i<100001; $i++ ) { $string = ' '.$var.' '.$var.' '.$var.' '.$var.' '.$var.' '.$var.' '.$var.' '.$var.' '.$var.' '.$var.' '.$var.' '.$var.' '.$var.' '.$var.' '.$var; unset( $string ); } $tempoFinal = microtime(true); echo '<br />One string with 15 instances of $var was set using multiple concats 100000 times and took '.number_format(($tempoFinal - $tempoInicial), 3, ',', '.').' seconds to execute'; $tempoInicial = microtime(true); for( $i=0; $i<100001; $i++ ) { $string = sprintf( ' %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s', $var, $var, $var, $var, $var, $var, $var, $var, $var, $var, $var, $var, $var, $var, $var ); unset( $string ); } $tempoFinal = microtime(true); echo '<br />One string with 15 instances of $var was set using sprintf with 15 tokens variables 100000 times and took'.number_format(($tempoFinal - $tempoInicial), 3, ',', '.').' seconds to execute'; $tempoInicial = microtime(true); for( $i=0; $i<100001; $i++ ) { $string = sprintf( ' %1$s %1$s %1$s %1$s %1$s %1$s %1$s %1$s %1$s %1$s %1$s %1$s %1$s %1$s %1$s', $var ); unset( $string ); } $tempoFinal = microtime(true); echo '<br />One string with 15 instances of $var was set using sprintf with 15 tokens variables 100000 times and took'.number_format(($tempoFinal - $tempoInicial), 3, ',', '.').' seconds to execute'; } Resultado (apenas dois): var = int( 1 ) One string with 15 instances of $var was set using multiple concats 100000 times and took 0,628 seconds to execute One string with 15 $vars was set using one concat 100000 times and took 0,428 seconds to execute One string with 15 instances of $var was set using sprintf with 15 tokens variables 100000 times and took0,664 seconds to execute One string with 15 instances of $var was set using sprintf with 15 tokens variables 100000 times and took0,876 seconds to execute var = int( 1 ) One string with 15 instances of $var was set using multiple concats 100000 times and took 0,615 seconds to execute One string with 15 $vars was set using one concat 100000 times and took 0,424 seconds to execute One string with 15 instances of $var was set using sprintf with 15 tokens variables 100000 times and took0,665 seconds to execute One string with 15 instances of $var was set using sprintf with 15 tokens variables 100000 times and took0,841 seconds to execute A diferença foi mínima, mas todos os testes demonstraram que aspas duplas é mais performático. É bem interessante notar a evolução do core do PHP. Lembrando que esse código estava no manual do php. Edit---- Tenho de colocar uma consideração. Talvez, apóstrofo, seja mais performático em menos concatenações. O teste do Henrique foi com mil registros, o do manual, foi com 100 mil. Isso também deve ser levado em consideração. A quantidade variáveis também deve ser levada em consideração. Não desconsiderando nenhum teste. Mas isso já ser torna um pouco de mito entre ambos os modos. Edit 2---- Link do teste original: http://www.php.net/manual/pt_BR/language.operators.string.php#71062 Encontrei a explicação dada por um desenvolvedor. Segue: Use double quotes to concat more than two strings instead of multiple '.' operators. PHP is forced to re-concatenate with every '.' operator. O que esclarece uma das minhas considerações. Para 3 ou mais variáveis, aspas duplas se torna mais performático. Compartilhar este post Link para o post Compartilhar em outros sites
Henrique Barcelos 290 Denunciar post Postado Julho 13, 2012 Pois então, pra dar uma diferença significativa, você tem que fazer algumas mil concatenações... Como provavelmente nem faça desse tanto no sistema inteiro em uma única requisição, aí vai do gosto do cliente mesmo. Eu gosto bastante da sintaxe dos *printf quando vou lançar exceções cuja mensagem tem variáveis. Normalmente uso aspas simples por causa do agora mito de ser mais rápido, agora vou considerar voltar às aspas duplas também... :grin: Compartilhar este post Link para o post Compartilhar em outros sites
Gabriel Heming 766 Denunciar post Postado Julho 13, 2012 É bem interessante essa evolução. Eu gosto de aspas duplas pois vim do Java. Entretanto, não gosto de não concatenar a variável, fica muito perdido em textos longos. Também uso bastante o printf e sprintf. Se tornou uma função muito útil. Compartilhar este post Link para o post Compartilhar em outros sites