APC 与 Memcache 取数据性能对比

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

看来也不是越少越好。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值