<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Codigo Manso &#187; bucles</title>
	<atom:link href="http://www.codigomanso.com/es/tag/bucles/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.codigomanso.com</link>
	<description>Programación, informática y tecnología</description>
	<lastBuildDate>Sun, 21 Aug 2011 10:54:29 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Un error común en programación</title>
		<link>http://www.codigomanso.com/es/2008/11/un-error-comun-en-programacion/</link>
		<comments>http://www.codigomanso.com/es/2008/11/un-error-comun-en-programacion/#comments</comments>
		<pubDate>Wed, 26 Nov 2008 09:28:16 +0000</pubDate>
		<dc:creator>Pau Sanchez</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programacion]]></category>
		<category><![CDATA[bucles]]></category>
		<category><![CDATA[c]]></category>
		<category><![CDATA[error comun]]></category>

		<guid isPermaLink="false">http://www.codigomanso.com/?p=156</guid>
		<description><![CDATA[Un error que comete mucha gente, aunque mucha no se da cuenta, y la mayoría de veces pasa desapercibido, se da a la hora de poner las condiciones en los bucles. Se debe tener cuidado cuando se hacen llamadas dentro de un bucle, porque algo que a priori puede parecer O(n) se convierte en O(n2).
¿Alguien [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Un error que comete mucha gente, aunque mucha no se da cuenta, y la mayoría de veces pasa desapercibido, se da a la hora de poner las condiciones en los bucles. Se debe tener cuidado cuando se hacen llamadas dentro de un bucle, porque algo que a priori puede parecer O(n) se convierte en O(n<sup>2</sup>).</p>
<p style="text-align: justify;">¿Alguien ve algo raro en el siguiente código?</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$i</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> <span style="color: #000088;">$i</span> <span style="color: #339933;">&lt;</span> <span style="color: #990000;">strlen</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$string</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000088;">$i</span><span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// whatever this loop does</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p style="text-align: justify;">A priori ¿Parece que todo está bien, no? Si te lo parece es que no eres consciente aún.</p>
<p style="text-align: justify;">Es bien sabido que las condiciones de los bucles se evaluan tantas veces como iteraciones tiene el bucle, con esto no estoy descubriendo nada a nadie, sin embargo, si se mete un <strong>strlen</strong> para medir la longitud de la cadena en un bucle que se ejecuta tantas veces como caracteres hay, acabamos de elevar al cuadrado el tiempo de ejecución.</p>
<p style="text-align: justify;">Tanto en C como en PHP, la función <strong>strlen</strong> necesita recorrer toda la cadena hasta encontrar el &#8216;\0&#8242; para determinar su longitud, así pues, si la longitud es 20, strlen necesitará 20 iteraciones para determinar que la longitud es 20. El problema es que el bucle que estamos haciendo también tiene 20 iteraciones, y en cada iteración se ejecuta strlen, que consume otras 20 iteraciones (claro que en PHP esas 20 iteraciones se ejecutan en código máquina, y no en el interprete), por lo que tendríamos que el coste de ese bucle para una cadena de 20 caracteres es de 20*(20 + lo que hay dentro del bucle) = 400 + 20*lo que hay dentro del bucle.</p>
<p style="text-align: justify;">El siguiente script (<a href="http://www.codigomanso.com/archives/phpscripts/common_mistake_with_loops_using_strlen.php.txt" target="_blank">error común con los bucles</a>) muestra un ejemplo de esto en PHP, donde dentro del bucle no se hace nada, y se puede observar como un bucle es mucho más lento que el otro.</p>
<p style="text-align: justify;">Los resultados tras ejecutarlo en mi ordenador han sido:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">strlen($sentence) =  12608 bytes
Making the common mistake: 3.02566313744 seconds
Fixing the common mistake: 0.958508968353 seconds</pre></div></div>

<p style="text-align: justify;">Creo que se puede apreciar claramente la diferencia <img src='http://www.codigomanso.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p style="text-align: justify;">Finalmente, aunque he usado PHP para ilustrar el error, y concretamente <strong>strlen</strong>, si nos olvidamos de strlen y de PHP, esto es aplicable a otros muchos lenguages C/C++/Java/Pascal/PHP/Python/Perl/Ruby y un largo etcetera; y pasa en todos los lenguajes porque todos los lenguajes usan el mismo concepto, la condicion de salida del bucle se evalua en cada iteración. Quizás no ocurra cuando se utilizan cadenas, porque guardan la longitud en una variable, pero puede que pase al mirar la longitud de listas enlazadas, etc&#8230;</p>
<p style="text-align:justify;"><strong>Conclusión:</strong> si en el bucle estás llamando a una función que siempre te va a devolver lo mismo, mejor guardalo en una variable y usa esa variable dentro del bucle, te ahorrará sorpresas</p>
<p style="text-align:justify;">
<p><strong>Enlaces interesantes:</strong></p>
<ul>
<li><a href="http://www.joelonsoftware.com/articles/fog0000000319.html" target="_blank">Back to basics</a>, un excelente artículo de Joel (<a href="http://local.joelonsoftware.com/mediawiki/index.php/De_vuelta_a_lo_b%C3%A1sico" target="_blank">disponible en Español</a>) donde reflexiona sobre algunas cosas directamente relacionadas con esto.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.codigomanso.com/es/2008/11/un-error-comun-en-programacion/feed/</wfw:commentRss>
		<slash:comments>44</slash:comments>
		</item>
	</channel>
</rss>

