需求:
根据一些指定的计算公式去获得期待值。例子:
//提供的数据源
$row = array(
'pv' => 50,
'uv' => 6,
'st' => 650,
'nuv' => 2
);
//需求公式,可能有些量不存在:如no
$gx = '(pv+uv)/(uv-nuv+1)*10+nuv-uv+no/0+3.5';
$gx = preg_replace('/[a-z][a-z_\d]+/i', ' $row[\'${0}\'] ', $gx);//处理过后公式
$str = "@\$s = $gx;";//合法php语句
try{
@eval($str);//str和eval前使用@确保不显示错误,如某个变量不存在,或除数为0等
}catch(Exception $e){}//这个方结果可求出
这个方法,可能大家都想到,还有一些这个方法的变异:
1,使用 preg_replace_callback
2,preg_replace('//ie')使用e修正符,其实与1一样
3,使用sql来执行公司,"select 格式化后的公式",但这个方法不能处理no这个变量,还有除数为0时,会返回null
//以上是我目前的方法
循环1w次,0.25秒左右,
如果10w次,就2秒多了。这个效率目前还接受不了。哥们还有什么好办法没????
根据一些指定的计算公式去获得期待值。例子:
//提供的数据源
$row = array(
'pv' => 50,
'uv' => 6,
'st' => 650,
'nuv' => 2
);
//需求公式,可能有些量不存在:如no
$gx = '(pv+uv)/(uv-nuv+1)*10+nuv-uv+no/0+3.5';
$gx = preg_replace('/[a-z][a-z_\d]+/i', ' $row[\'${0}\'] ', $gx);//处理过后公式
$str = "@\$s = $gx;";//合法php语句
try{
@eval($str);//str和eval前使用@确保不显示错误,如某个变量不存在,或除数为0等
}catch(Exception $e){}//这个方结果可求出
这个方法,可能大家都想到,还有一些这个方法的变异:
1,使用 preg_replace_callback
2,preg_replace('//ie')使用e修正符,其实与1一样
3,使用sql来执行公司,"select 格式化后的公式",但这个方法不能处理no这个变量,还有除数为0时,会返回null
//以上是我目前的方法
循环1w次,0.25秒左右,
如果10w次,就2秒多了。这个效率目前还接受不了。哥们还有什么好办法没????
echo ( $row['pv'] + $row['uv'] )/( $row['uv'] - $row['nuv'] +1)*10+ $row['nuv'] - $row['uv'] + $row['no'] /0+3.5;
速度应该是最快的了吧,但测试结果也一样。
//提供的数据源,需要先进行排序,将字符数多的键排前面
$row = array(
'nuv' => 2,
'pv' => 50,
'uv' => 6,
'st' => 650,
);$search = array_keys($row);
$replace = array_values($row);function cal()
{
global $search, $replace; //需求公式,可能有些量不存在:如no
$gx = '(pv+uv)/(uv-nuv+1)*10+nuv-uv+no/0+3.5';
$gx = str_replace($search, $replace, $gx);// 改用str_replace替代preg_replace,效率会高一些
$str = "@\$s = $gx;";//合法php语句
try{
@eval($str);//str和eval前使用@确保不显示错误,如某个变量不存在,或除数为0等
}catch(Exception $e){}
}
$t1 = microtime(true);
for ($i = 0; $i < 10000; $i++)
{
cal();
}
echo microtime(true) - $t1;// output: 0.18727397918701
多谢你的回答。你这个方法我也试用过,但会出现一些问题的
$gx = str_replace($search, $replace, $gx);$row = array(
'uv' => 50,
'nuv' => 60
);
$gx = 'uv+nuv+uv';
$gx = str_replace($search, $replace, $gx);
//输出:50+n50+50但主要的效率存在于 eval 这里,str_replace 替换 preg 这个方式,提升的效率不太理想
分别测试了正则和eval的耗时,preg_replace 占 30%多点,eval 占 60% 多点
仅从代码层面是不能解决问题的
你或许应考虑预编译到程序文件或phar