需求:
根据一些指定的计算公式去获得期待值。
例子:
//提供的数据源$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){}//这个方结果可求出
都来讨论一下。。。。
先支持一下楼主
还想怎么快,没法再快了。你直接用数据值计算:
echo ( $row['pv'] + $row['uv'] )/( $row['uv'] - $row['nuv'] +1)*10+ $row['nuv'] - $row['uv'] + $row['no'] /0+3.5;
速度应该是最快的了吧,但测试结果也一样。
第二种e 的效率测试了没有,感觉会快点呢。
还想怎么快,没法再快了。你直接用数据值计算:
echo ( $row['pv'] + $row['uv'] )/( $row['uv'] - $row['nuv'] +1)*10+ $row['nuv'] - $row['uv'] + $row['no'] /0+3.5;
速度应该是最快的了吧,但测试结果也一样。
你还没看清需求吧,如果公式变了呢?
有几百个公式呢?
第二种e 的效率测试了没有,感觉会快点呢。
基本一样,e修正符就是把replace当成eval来执行了
//提供的数据源,需要先进行排序,将字符数多的键排前面$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
PHP code?123456789101112131415161718192021222324252627282930313233//提供的数据源,需要先进行排序,将字符数多的键排前面$row = array( 'nuv' => 2, 'pv' => 50, 'uv' => 6, ……
多谢你的回答。
你这个方法我也试用过,但会出现一些问题的
$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
一万次 0.25 秒已经够快了
eval 时有一个语法分析过程,比较耗时
分别测试了正则和eval的耗时,preg_replace 占 30%多点,eval 占 60% 多点
仅从代码层面是不能解决问题的
你或许应考虑预编译到程序文件或phar
引用 7 楼 ustb 的回复:PHP code?123456789101112131415161718192021222324252627282930313233//提供的数据源,需要先进行排序,将字符数多的键排前面$row = array( 'nuv' => 2, 'pv' => 50, 'uv'……
第一行就说了需要先排序的。。。
引用 8 楼 yangball 的回复:引用 7 楼 ustb 的回复:PHP code?123456789101112131415161718192021222324252627282930313233//提供的数据源,需要先进行排序,将字符数多的键排前面$row = array( 'nuv' => 2, 'pv' ……
哦,不好意思,没留意着。
先排序是能解决。
1万回0.25秒でも十分速い
evalには構文解析処理があり、かなり時間がかかる
時間のかかるregulatorとevalをそれぞれテストしたところ、preg_replaceが30%以上、evalが30%以上を占めた60%
からのみ この問題はコードレベルでは解決できません
おそらくプログラムファイルまたは phar にプリコンパイルすることを検討する必要があります
現時点ではこれより良い方法はありません。とりあえずこの方法を使ってみましょう。
それを実現するには拡張機能を書いた方が確実なようです
十分速いですが、どれくらいの速度が欲しいですか、そしてどのような自転車が必要ですか?