4000多条道具数据,序列化之后4M大小。
结果是:
Memcache平均取速度为:0.134032303095秒
Apc平均取速度为:0.346668326855秒
真心没想到啊。网上没看到apc是否序列化的说明。我想既然是个扩展,那么应该是设置一个指针指向这个变量,取的时候直接把这个地址转换成zval,就可以直接用了。结果看来不是这样的。
------------------------------
然后我只取1000条数据,发现情况有所不同:
Memcache平均取速度为:0.000312173367秒
Apc平均取速度为:0.000287636121秒
眼睛又被辣到了。数据少了3/4,性能提升 400 - 1000倍!
------------------------------
然后我只取2000条数据,情况是:
Memcache平均取速度为:0.000837951899秒
Apc平均取速度为:0.000848603249秒
多1000条数据,时间多了不少。
=======================================
总结起来,memcache除开socket链接时间,速度快于apc。
但主要的问题还是在于反序列化的时间。
附上测试代码:
<?php
function llog($s){
file_put_contents(ERR_LOG_FILE,chr(10).$s,FILE_APPEND);
}
if(!defined('ERR_LOG_FILE')){
function shutdown(){
if(defined(MY_LOG))
file_put_contents(MY_LOG,chr(10).'============== shutdown => '.$_SERVER['REQUEST_URI'].' ==============',FILE_APPEND);
else
llog('============== shutdown => '.$_SERVER['REQUEST_URI'].' ==============');
if(defined('ERR_LOG_FILE')){
$_error=error_get_last();
if($_error && in_array($_error['type'],array(1,4,16,64,256,4096,E_ALL))){
$s = chr(10).'---------------------'.chr(10).date('Y/m/d H:i:s').' error:'.$_error['message'].chr(10);
$s .= 'File:'.$_error['file'].chr(10);
$s .= 'Line:'.$_error['line'].chr(10);
file_put_contents(ERR_LOG_FILE, $s , FILE_APPEND);
}
}
}
register_shutdown_function("shutdown");
define('ERR_LOG_FILE', PHP_OS!='WINNT'?'/tmp/wx.txt':'c:/pk_php.txt');
if(defined('ERR_LOG_FILE')){
ini_set("display_errors",0);//不在页面显示错误信Ï?
error_reporting(E_ALL ^ E_NOTICE);//记录错误日志的¼侗??
ini_set( "log_errors", "On" );//打开错误日志
ini_set( "error_log", ERR_LOG_FILE);//设置保存错误日志的地址
}
}
$conn = mysql_connect("localhost", "lein", "123456");
if (!$conn) {
echo "Unable to connect to DB: " . mysql_error();
exit;
}
if (!mysql_select_db("pm03")) {
echo "Unable to select mydbname: " . mysql_error();
exit;
}
function microtime_float()
{
list($usec, $sec) = explode(" ", microtime());
return ((float)$usec + (float)$sec);
}
$m = memcache_connect('127.0.0.1',11211);
$t= isset($_GET['t'])?$_GET['t']:1;
$key = 'propsr18'.$_GET['p'];
if($t==2)
$d = memcache_get($m,$key);
//memcache_delete($key,0);
if(
($t==1&&!apc_exists($key))
||
($t==2&&!$d)
){
$sql = "SELECT * FROM abc";
$result = mysql_query($sql);
if (!$result) {
echo "Could not successfully run query ($sql) from DB: " . mysql_error();
exit;
}
if (mysql_num_rows($result) == 0) {
echo "No rows found, nothing to print so am exiting";
exit;
}
$rows = array();
$c = 2000;
while ($row = mysql_fetch_assoc($result)&&$c--) {
$rows[] = $row;
}
apc_add($key.'time',time());
if($t==1)
apc_add($key, $rows);
else{
echo count($rows).chr(10);
memcache_set($m, $key, $rows,0,600);
echo count(memcache_get($m, $key));
}
}
else{
echo 'Cache at:'.date('Y-m-d H:i:s',apc_fetch($key.'time')).'<br/>';
$s = microtime_float();
for($i=1;$i<101;$i++){
if($t==1)
$d = apc_fetch($key);
else
$d = memcache_get($m, $key);
if($i%10==0){
echo $i.' ';
printf("%16.12f",(microtime_float()-$s)/$i);
echo ', count='.count($d).'</br>';
}
}
printf("%16.12f",(microtime_float()-$s)/$i);
echo '<br/>';
echo strlen(serialize($d))/1024;
}
?>
下面是开动脑筋的时间了。改造下存储方法,把长数据分成多个存储,取出时取多次再合并。
define('_AMC_SIZE', 500); function Apc_add1($key, $v){ $c = count($v); $i = 0; $count = 0; while($i<$c){ $data = array_slice($v,$i,_AMC_SIZE); $i+=_AMC_SIZE; $k = '__SLD_'.$count.'_'.$key; apc_add($k, $data); $count++; } } function Apc_get1($key){ $count = 0; $arr = array(); while(1){ $k = '__SLD_'.$count.'_'.$key; $d = apc_fetch($k); $arr = array_merge($arr,$d); $count++;
if(count($d)<_AMC_SIZE) break;
}
} 结果:return $arr;
500条存一个,平均时间:0.006096243858秒
1000条存一个,平均时间:0.004376041889
看来也不是越少越好。