<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
<title><![CDATA[向东博客 专注WEB应用 构架之美 --- 构架之美，在于尽态极妍 | 应用之美，在于药到病除]]></title> 
<link>http://www.jackxiang.com/index.php</link> 
<description><![CDATA[赢在IT，Playin' with IT,Focus on Killer Application,Marketing Meets Technology.]]></description> 
<language>zh-cn</language> 
<copyright><![CDATA[向东博客 专注WEB应用 构架之美 --- 构架之美，在于尽态极妍 | 应用之美，在于药到病除]]></copyright>
<item>
<link>http://www.jackxiang.com/post//</link>
<title><![CDATA[为何Python这么快 ]]></title> 
<author>jack &lt;xdy108@126.com&gt;</author>
<category><![CDATA[WEB2.0]]></category>
<pubDate>Fri, 07 Sep 2007 09:37:09 +0000</pubDate> 
<guid>http://www.jackxiang.com/post//</guid> 
<description>
<![CDATA[ 
	问题的提出是源于 这位兄弟的BLOG，在他的这个实现中，Python具有相当不错的性能，不但优于帖子中的C实现性能，也优于随后的跟贴中众多的C++实现的性能。<br/><br/>在经过了多次尝试，我还是很难找出一个优于Python性能的实现。这不是一件正常的事情，Python的性能注定不会优于C/C++，这是因为Python是解释执行的，解释的过程必然会消耗CPU时间，所以我查阅了Python的源码试图找出为何Python对于这个任务有如此好的性能的原因。<br/><br/>任务描述如下<br/><br/>对于一个78W行的文本文件，每一行是一个Email地址，文件中存在有重复的行，任务的要求是尽可能快的从这个文本文件生成一个无重复的Email的文本文件<br/><br/>一些相关的实现，可以参看这个地址<br/>有如下的三个问题需要注意<br/><br/>对于这种大量的字符串比较，直接使用字符串比较函数是严重妨碍性能的 <br/>IO性能是要注意的 <br/>尽可能的少使用占用内存 <br/>在我的尝试中，发现重复调用 ofstream::operator&lt;&lt; 是比较影响性能的，而使用 fprintf或使用copy 等 STL 算法输出到则性能好的多。使用一种好的Hash算法是影响程序性能的关键。任务中的EMail字符串总是具有[a-z]*[0-9]*@([a-z]*&#92;.)+[a-z]* 的形式，例如 joson123@sina.com.cn joson72345@sina.com.cn 的格式。 <br/><br/>在$PySrc/Objects/dictobject.c 中，对Python的Hash机制作了一些描述，总的来说，Python的Hash机制对于这种连续型的字符串有相当好的离散度，对于这个 78W 例子，python_hash() % 780000能够很均匀的分散到各个值，最大的冲突数为 8。 以下是按照类似 Python的 Hash算法实现的 C++ 版本的结果 <br/><br/>E:&#92;Workspace&#92;Temp&#92;Email&gt;my 经过了1687.5000毫秒 E:&#92;Workspace&#92;Temp&#92;Email&gt;my 经过了1718.7500毫秒 E:&#92;Workspace&#92;Temp&#92;Email&gt;my 经过了1671.8750毫秒 E:&#92;Workspace&#92;Temp&#92;Email&gt;my 经过了1656.2500毫秒 E:&#92;Workspace&#92;Temp&#92;Email&gt;py_email.py 2.82014641526 E:&#92;Workspace&#92;Temp&#92;Email&gt;py_email.py 2.74879181572 E:&#92;Workspace&#92;Temp&#92;Email&gt;py_email.py 2.76348586203 E:&#92;Workspace&#92;Temp&#92;Email&gt;dir *.txt 2006-03-28 &nbsp;13:09 &nbsp; &nbsp; &nbsp; &nbsp;19,388,869 email.txt 2006-03-29 &nbsp;22:51 &nbsp; &nbsp; &nbsp; &nbsp;17,779,266 email_new.txt (py_email.py 写出) 2006-03-29 &nbsp;22:50 &nbsp; &nbsp; &nbsp; &nbsp;17,779,266 email_new_my.txt (my.exe 写出) <br/>py_email.py 的实现参看这里 my.cpp 实现如下 使用 cl /O2 /EHsc /D_CRT_SECURE_NO_DEPRECATE my.cpp 编译<br/>#include &lt;cstdio&gt; #include &lt;windows.h&gt; &nbsp;using namespace std; #define c_mul(a, b) (a * b &amp; 0xFFFFFFFF) size_t python_hash(const char * str) { &nbsp;&nbsp;size_t value = str[0] &lt;&lt; 7; &nbsp;&nbsp;size_t len = 0; &nbsp;&nbsp;while(*str != 0) &nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;value = c_mul(1000003, value) ^ *str++; &nbsp;&nbsp;&nbsp;&nbsp;len++; &nbsp;&nbsp;} &nbsp;&nbsp;value = value ^ len; &nbsp;&nbsp;if (value == (size_t)-1) &nbsp;&nbsp;value = (size_t)-2; &nbsp;&nbsp;return value; } size_t hash(const char * str, size_t seed = 1) { &nbsp;&nbsp;size_t h = 0, g; &nbsp;&nbsp;&nbsp;size_t len = 0; &nbsp;&nbsp;while (*str)&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;h = (h &lt;&lt; 4) + *str++; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ((g = (h &amp; 0xF0000000))) { &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;h = h ^ (g &gt;&gt; 24); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;h = h ^ g; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;h = h ^ seed; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;len++; &nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;return h; &nbsp;} #define MAX_TABLE_SIZE (780000) #define MAX_CONFI 9 struct hash_item { &nbsp;&nbsp;size_t items[MAX_CONFI]; &nbsp;&nbsp;size_t item_count; &nbsp;&nbsp;hash_item() &nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;item_count = 0; &nbsp;&nbsp;} &nbsp;&nbsp;bool check_has(const char * str) &nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;size_t key = hash(str); &nbsp;&nbsp;&nbsp;&nbsp;for(size_t i = 0; i &lt; item_count; i++) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (items[i] == key) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return true; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;items[item_count++] = key; &nbsp;&nbsp;&nbsp;&nbsp;return false; &nbsp;&nbsp;} }; int main( void ) { &nbsp;&nbsp;__int64 t1, t2; &nbsp;&nbsp;GetSystemTimeAsFileTime( (LPFILETIME)&amp;t1 ); &nbsp;&nbsp;FILE * fin = fopen(&quot;email.txt&quot;, &quot;r&quot;); &nbsp;&nbsp;FILE * fout = fopen(&quot;email_new_my.txt&quot;, &quot;w+&quot;); &nbsp;&nbsp;size_t hash_key_a = 0; &nbsp;&nbsp;size_t hash_key_b = 0; &nbsp;&nbsp;size_t pos_x = 0; &nbsp;&nbsp;size_t pos_y = 0; &nbsp;&nbsp;const char * buffer = NULL; &nbsp;&nbsp;char line[255]; &nbsp;&nbsp;fgets(line, 255, fin); &nbsp;&nbsp;hash_item * table = new hash_item[MAX_TABLE_SIZE]; &nbsp;&nbsp;while(!feof(fin)) &nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;buffer = line; &nbsp;&nbsp;&nbsp;&nbsp;hash_key_a = python_hash(buffer); &nbsp;&nbsp;&nbsp;&nbsp;pos_x = hash_key_a % MAX_TABLE_SIZE; &nbsp;&nbsp;&nbsp;&nbsp;if (!table[pos_x].check_has(buffer)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fprintf(fout, &quot;%s&quot;, buffer); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fgets(line, 255, fin); &nbsp;&nbsp;} &nbsp;&nbsp;GetSystemTimeAsFileTime( (LPFILETIME)&amp;t2 ); &nbsp;&nbsp;printf( &quot;经过了%I64d.%04I64d毫秒&#92;n&quot;, (t2-t1)/10000, (t2-t1)%10000 ); &nbsp;&nbsp;fclose(fin); &nbsp;&nbsp;fclose(fout); &nbsp;&nbsp;delete [] table; } <br/><br/><br/>[url=http://wiki.woodpecker.org.cn/moin/BPUG]啄木鸟Python开源社区 [/url]
]]>
</description>
</item><item>
<link>http://www.jackxiang.com/post//#blogcomment</link>
<title><![CDATA[[评论] 为何Python这么快 ]]></title> 
<author> &lt;user@domain.com&gt;</author>
<category><![CDATA[评论]]></category>
<pubDate>Thu, 01 Jan 1970 00:00:00 +0000</pubDate> 
<guid>http://www.jackxiang.com/post//#blogcomment</guid> 
<description>
<![CDATA[ 
	
]]>
</description>
</item>
</channel>
</rss>