php排序1亿个QQ号码
吃饱喝足了,还发贴了。
拆开分成几千份进行排序再合并。
首先先创建一个1亿个QQ号的txt。
<br><?php<br><br>// 创建一亿个QQ号的txt (大约需85~100秒)<br><br>set_time_limit(0);<br>$fn = 'qq.txt';<br>$fp = fopen($fn, 'w');<br><br>$st = microtime(true);<br><br>$l = range(0,10000);<br>shuffle($l);<br>foreach ($l as $k=>$v)<br>{<br> $arr = range($v*10000+10000,10000*($v+1)+9999);<br> shuffle($arr);<br> fputs($fp,implode("
", $arr)."
");<br> unset($arr);<br>}<br><br>echo microtime(true)-$st;<br><br>?><br>
稍等一两分钟1亿个随机qq创建完成了。
qq号码范围为>10000。文件大小大概有840mb。
下面就进行分类划分成几千份文件。
以qq号码长度为文件夹,qq号码前3位为文件名。
<br><?php<br><br>// 长度号码分类 (大约需360~400秒)<br><br>set_time_limit(0);<br>$st = microtime(true);<br><br>if(!is_dir('qq_no')) mkdir('qq_no');<br>$file = fopen('qq.txt', 'r'); <br><br><br>$i=0;<br>$end_s = '';<br>while(!feof($file))<br>{<br> $g = 1042*1024;<br> fseek($file,$g*$i);<br> $s = fread($file, $g);<br><br> <br> $end = strrpos($s, "
");<br> $arr_s = $end_s.substr($s, 0, $end);<br> $end_s = substr($s, $end);<br><br> $arr = explode("
", $arr_s);<br> foreach ($arr as $k=>$v)<br> {<br> if($v!='')<br> {<br> $tag = "$v[0]$v[1]$v[2]";<br> $text_arr[strlen($v)][$tag][] = $v;<br> }<br> }<br><br> foreach ($text_arr as $k=>$v)<br> {<br> $n_dir = 'qq_no/'.$k;<br> if (!is_dir($n_dir)) mkdir($n_dir);<br> foreach ($v as $tag=>$val)<br> {<br> $n_tf = fopen($n_dir.'/'.$tag.'.txt', 'a+');<br> fputs($n_tf,implode("
",$val)."
");<br> }<br> <br> <br> }<br> unset($text_arr);<br><br> ++$i;<br><br>}<br><br>echo microtime(true)-$st;<br><br>?><br>最后就要每个文件进行排序合并数据了。
<br><?php<br><br>// 排序完成拉 (800~920秒)<br><br>set_time_limit(0);<br>$st = microtime(true);<br><br>$qq_done = fopen('qq_done.txt', 'a+');<br><br>$root = 'qq_no';<br>$dir_array = scandir($root);<br><br>foreach ($dir_array as $key=>$val)<br>{<br> if ($val != '.' && $val != '..')<br> $dirs[$val] = scandir($root.'/'.$val);<br>}<br><br><br>foreach ($dirs as $key=>$val)<br>{<br> foreach ($val as $v)<br> {<br> if ($v != '.' && $v != '..')<br> {<br> $file = $root. '/' . $key . '/'. $v;<br> $c = file_get_contents($file);<br> $arr = explode("
", $c);<br> sort($arr);<br> fputs($qq_done, implode("
",$arr));<br> unlink($file);<br> }<br> }<br> rmdir($root. '/' . $key);<br>}<br>rmdir($root);<br><br>echo microtime(true)-$st;<br><br>?><br>总共大概花费了20多分钟。
虽然完成了,但方法很土鳖 0_0 ,坛里各位高手们改进改进啊。
------解决方案--------------------
来个C版本的
<br>#include <stdio.h><br><br>#define BITSPERWORD 32<br>#define SHIFT 5<br>#define MASK 0x1F<br>#define N 100000000<br><br>int a[1 + N/BITSPERWORD];<br><br>void set(int i)<br>{<br> a[i>>SHIFT] <br><font color="#FF8000">------解决方案--------------------</font><br>= (1<<(i & MASK)); //i&MASK相当于1&(32-1),即1%32<br>}<br><br>void clr(int i)<br>{<br> a[i>>SHIFT] &= ~(1<<(i & MASK));<br>}<br><br>int test(int i)<br>{<br> return a[i>>SHIFT] & (1<<(i & MASK));<br>}<br><br>int main()<br>{<br> int i;<br> //初始化<br> for(i = 0; i < N; i++)<br> clr(i);<br><br> //读取文件,置位<br> while(scanf("%d", &i) != EOF)<br> set(i);<br><br> for(i = 0; i < N; i++)<br> if(test(i))<br> printf("%d
", i);<br><br> return 0;<br>}<br>------解决方案--------------------
既然有现成的数据文件,就没有必要去构造插入串了
set_time_limit(0);<br>$sql =<<< SQL<br>CREATE TABLE IF NOT EXISTS qq1 (<br> `qq` int(10) NOT NULL,<br> KEY `qq` (`qq`)<br>) ENGINE=MyISAM DEFAULT CHARSET=utf8;<br>SQL;<br><br>mysql_connect('localhost', 'root', '');<br>mysql_select_db('test');<br>mysql_query($sql);<br><br>$filename = str_replace('\', '/', realpath('qq.txt'));<br>$sql =<<< SQL<br>LOAD DATA INFILE '$filename' INTO TABLE qq1<br>SQL;<br><br>check_speed(1);<br>mysql_query($sql) or print(mysql_error());;<br>check_speed();<br>时间: 182,955,851 微秒
内存: 664
立即学习“PHP免费学习笔记(深入)”;
<br>set_time_limit(0);<br>mysql_connect('localhost', 'root', '');<br>mysql_select_db('test');<br><br>echo '升序<br />';<br>$filename = str_replace('\', '/', dirname(__FILE__) . '/qq_1.txt');<div class="clear">
</div>











