<?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; cl</title>
	<atom:link href="http://www.codigomanso.com/es/tag/cl/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: Lenguajes compilados</title>
		<link>http://www.codigomanso.com/es/2008/11/un-error-comun-en-programacion-lenguajes-compilados/</link>
		<comments>http://www.codigomanso.com/es/2008/11/un-error-comun-en-programacion-lenguajes-compilados/#comments</comments>
		<pubDate>Wed, 26 Nov 2008 18:41:59 +0000</pubDate>
		<dc:creator>Pau Sanchez</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[cl]]></category>
		<category><![CDATA[compilador]]></category>
		<category><![CDATA[error comun]]></category>
		<category><![CDATA[g++]]></category>
		<category><![CDATA[interprete]]></category>
		<category><![CDATA[optimizar]]></category>
		<category><![CDATA[Programacion]]></category>

		<guid isPermaLink="false">http://www.codigomanso.com/?p=167</guid>
		<description><![CDATA[Juanjo ha apuntado que muy probablemente esto que yo comentaba como un típico error que la gente comete cuando programa, se optimiza en los lenguajes compilados (vease C/C++/Java/&#8230;).
Lo que proponía Juanjo (de probarlo con el g++ optimizando a tope) me ha parecido buena idea, así que he hecho unas cuantas pruebas en C++. 
Los resultados [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;"><a href="http://blackshell.usebox.net/" target="_blank">Juanjo</a> ha apuntado que muy probablemente esto que yo comentaba como un <a href="http://www.codigomanso.com/2008/11/un-error-comun-en-programacion/" target="_blank">típico error que la gente comete cuando programa</a>, se optimiza en los lenguajes compilados (vease C/C++/Java/&#8230;).</p>
<p style="text-align: justify;">Lo que proponía Juanjo (de probarlo con el g++ optimizando a tope) me ha parecido buena idea, así que he hecho unas cuantas pruebas en C++. </p>
<p>Los resultados han sido interesantes <img src='http://www.codigomanso.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p style="text-align: justify;">Para mi grata sorpresa, el g++ ha optimizado muy bien la función <strong>strlen</strong>. Sin embargo, no es capaz de optimizar &#8220;cualquier&#8221; función que tenga sus mismas características.</p>
<p style="text-align: justify;">En el archivo <strong>test-strlen.cpp</strong> he realizado varias pruebas (más abajo están los fuentes descargables en un .tgz).</p>
<p style="text-align: justify;">La primera prueba ha sido realizar un bucle con <strong>strlen</strong>, tal cual el código de PHP, y otro donde el <strong>strlen</strong> está fuera del bucle.</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"> <span style="color: #666666; font-style: italic;">// strlen dentro del bucle</span>
 <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span>j <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span> j <span style="color: #339933;">&lt;=</span> strlen <span style="color: #009900;">&#40;</span>str<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> j<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    copy <span style="color: #009900;">&#91;</span>j<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> str<span style="color: #009900;">&#91;</span>j<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
 <span style="color: #009900;">&#125;</span>
&nbsp;
 <span style="color: #808080; font-style: italic;">/* [...] */</span>
&nbsp;
 <span style="color: #666666; font-style: italic;">// strlen fuera del bucle</span>
 len <span style="color: #339933;">=</span> strlen <span style="color: #009900;">&#40;</span>str<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span>j <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span> j <span style="color: #339933;">&lt;=</span> len<span style="color: #339933;">;</span> j<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    copy <span style="color: #009900;">&#91;</span>j<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> str<span style="color: #009900;">&#91;</span>j<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
 <span style="color: #009900;">&#125;</span></pre></div></div>

<p style="text-align: justify;">Ha resultado que el g++ ha optimizado muy bien el primer bucle, hasta el punto que ambos probablemente ejecuten el mismo código, no se aprecia diferencia.</p>
<p style="text-align: justify;">Una vez hecho esto, me he dicho, voy a fastidiar un poco al compilador, así que he añadido una linea, que básicamente modifica <strong>str</strong>, que es la cadena que se le pasa al <strong>strlen</strong>, para que el compilador tenga que evaluar siempre el bucle:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"> <span style="color: #666666; font-style: italic;">// strlen dentro del bucle, modificando str</span>
 <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span>j <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span> j <span style="color: #339933;">&lt;=</span> strlen <span style="color: #009900;">&#40;</span>str<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> j<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    copy <span style="color: #009900;">&#91;</span>j<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> str<span style="color: #009900;">&#91;</span>j<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>j <span style="color: #339933;">==</span> <span style="color: #0000dd;">1</span><span style="color: #009900;">&#41;</span> str<span style="color: #009900;">&#91;</span>j<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> str<span style="color: #009900;">&#91;</span>j<span style="color: #339933;">-</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
 <span style="color: #009900;">&#125;</span></pre></div></div>

<p style="text-align: justify;">El caso es que ha funcionado, básicamente el compilador no lo ha podido optimizar, no obstante esto no me vale para ejemplificar lo que decía en el artículo anterior, porque el compilador ha hecho lo que tenía que hacer, y la variable ha sido modificada dentro.</p>
<p style="text-align: justify;">He aquí los resultados de <strong>test-strlen</strong>:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">Making the common mistake(not optimizable): 9.20
Making the common mistake(optimizable by the compiler): 0.00
Avoiding the common mistake: 0.00</pre></div></div>

<p style="text-align: justify;">Total, que he creado otro archivo de ejemplo, el <strong>test-custom-strlen.cpp</strong> cuyo objetivo es implementar una función equivalente a strlen y ver si el compilador es igual de inteligente.</p>
<p style="text-align: justify;">Básicamente, en este archivo he creado 5 funciones, vease: <strong>custom_strlen, custom_strlen_const, custom_strlen_const2, strlen_wrap, strlen_wrap_const</strong></p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">/** this is a custom strlen function */</span>
size_t custom_strlen <span style="color: #009900;">&#40;</span><span style="color: #993333;">char</span> <span style="color: #339933;">*</span>str<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
  <span style="color: #993333;">char</span> <span style="color: #339933;">*</span>ptr <span style="color: #339933;">=</span> str<span style="color: #339933;">;</span>
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>ptr <span style="color: #339933;">==</span> NULL<span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">return</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
  <span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span>ptr <span style="color: #339933;">!=</span> <span style="color: #ff0000;">'<span style="color: #006699; font-weight: bold;">\0</span>'</span><span style="color: #009900;">&#41;</span> ptr<span style="color: #339933;">++;</span>
  <span style="color: #b1b100;">return</span> <span style="color: #009900;">&#40;</span>size_t<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span>ptr <span style="color: #339933;">-</span> str<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">/** this is same as above, but telling the compiler we are not touching str*/</span>
size_t custom_strlen_const <span style="color: #009900;">&#40;</span><span style="color: #993333;">const</span> <span style="color: #993333;">char</span> <span style="color: #339933;">*</span>str<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
  <span style="color: #993333;">const</span> <span style="color: #993333;">char</span> <span style="color: #339933;">*</span>ptr <span style="color: #339933;">=</span> str<span style="color: #339933;">;</span>
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>ptr <span style="color: #339933;">==</span> NULL<span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">return</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
  <span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span>ptr <span style="color: #339933;">!=</span> <span style="color: #ff0000;">'<span style="color: #006699; font-weight: bold;">\0</span>'</span><span style="color: #009900;">&#41;</span> ptr<span style="color: #339933;">++;</span>
  <span style="color: #b1b100;">return</span> <span style="color: #009900;">&#40;</span>size_t<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span>ptr <span style="color: #339933;">-</span> str<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">/** this strlen updates input string, no matter that is const */</span>
size_t custom_strlen_const2 <span style="color: #009900;">&#40;</span><span style="color: #993333;">const</span> <span style="color: #993333;">char</span> <span style="color: #339933;">*</span>str<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
  <span style="color: #993333;">char</span> <span style="color: #339933;">*</span>ptr <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #993333;">char</span><span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span>str<span style="color: #339933;">;</span>
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>ptr <span style="color: #339933;">==</span> NULL<span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">return</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
  <span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span>ptr <span style="color: #339933;">!=</span> <span style="color: #ff0000;">'<span style="color: #006699; font-weight: bold;">\0</span>'</span><span style="color: #009900;">&#41;</span> ptr<span style="color: #339933;">++;</span>
&nbsp;
  <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #993333;">char</span><span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span>str<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #ff0000;">'a'</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// update string</span>
&nbsp;
  <span style="color: #b1b100;">return</span> <span style="color: #009900;">&#40;</span>size_t<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span>ptr <span style="color: #339933;">-</span> str<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">/** this is a wrapper over strlen function */</span>
size_t strlen_wrap <span style="color: #009900;">&#40;</span><span style="color: #993333;">char</span> <span style="color: #339933;">*</span>str<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #b1b100;">return</span> strlen <span style="color: #009900;">&#40;</span>str<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">/** this is a wrapper over strlen function with constant input */</span>
size_t strlen_wrap_const <span style="color: #009900;">&#40;</span><span style="color: #993333;">const</span> <span style="color: #993333;">char</span> <span style="color: #339933;">*</span>str<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #b1b100;">return</span> strlen <span style="color: #009900;">&#40;</span>str<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p style="text-align: justify;">Y los resultados ha sido los siguientes:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">using custom_strlen: 3.90
using custom_strlen_const: 4.05
using custom_strlen_const2: 4.04
using strlen_wrap: 0.00
using strlen_wrap_const: 0.00</pre></div></div>

<p style="text-align: justify;">Vamos, que el compilador, con -O3, no ha sido capaz de optimizar ninguna de mis funciones. Y el caso es que la función <strong>custom_strlen_const</strong> era candidata para ser optimizada igual que el strlen (función con un parámetro constante, internamente usa const para todo y no cambia el valor de nada).</p>
<p style="text-align: justify;">Total, que sigo manteniendo la misma opinión que en el artículo anterior: <strong>si una función se va a evaluar siempre a lo mismo, mejor que esté fuera del bucle, porque no se sabe si el compilador o intérprete va a ser capaz de optimizarla o no.</strong></p>
<p style="text-align: justify;">También me gustaría decir que por lo general este tipo de cosas, normalmente, tampoco va a suponer ningún cuello de botella en ninguna aplicación, ni va a suponer tiempos abismales de ejecución, por lo que no es preciso prestarle mucha importancia; ahora bien, son pequeños detalles, que se van sumando y sumando, y oye, quizá no reduzcan los tiempos un 30%, pero un 5%&#8230; <img src='http://www.codigomanso.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p style="text-align: justify;"><a href="http://www.codigomanso.com/archives/misc/test-gcc-strlen.tgz" target="_blank">Aquí teneis el archivo comprimido con los códigos fuentes de ejemplo</a>. (descomprimir, ejecutar make y listo)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.codigomanso.com/es/2008/11/un-error-comun-en-programacion-lenguajes-compilados/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>

