这是与Fastest way to determine if an integer is between two integers (inclusive) with known sets of values类似的问题,但由于php没有严格打字且没有可控制的整数溢出,所接受的答案在php中不起作用(据我所知)。
此处的用例是确定整数是否介于65和90之间(“A”和“Z”的ASCII值)。这些界限可能有助于优化解决方案,因为64是2的幂并且充当该问题的边界条件。
到目前为止我唯一提出的伪优化是:
//$intVal will be between 0 and 255 (inclusive)
function isCapital($intVal)
{
//255-64=191 (bit mask of 1011 1111)
return (($intVal & 191) <= 26) && (($intVal & 191) > 0);
}
与$intVal >= 65 && $intVal <= 90
的正常双重比较相比,此函数没有太大改进(可能更慢),但它正是我在尝试优化时开始前进的地方。
答案 0 :(得分:5)
function isCapitalBitwise($intVal) {
return (($intVal & 191) <= 26) && (($intVal & 191) > 0);
}
function isCapitalNormal($intVal) {
return $intVal >= 65 && $intVal <= 90;
}
function doTest($repetitions) {
$i = 0;
$startFirst = microtime();
while ($i++ < $repetitions) {
isCapitalBitwise(76);
}
$first = microtime() - $startFirst;
$i = 0;
$startSecond = microtime();
while ($i++ < $repetitions) {
isCapitalNormal(76);
}
$second = microtime() - $startSecond;
$i = 0;
$startThird = microtime();
while ($i++ < $repetitions) {
ctype_upper('A');
}
$third = $startThird - microtime();
echo $first . ' ' . $second . ' ' . $third . PHP_EOL;
}
doTest(1000000);
在我的系统上,它返回:
0.217393 0.188426 0.856837
PHP在按位运算方面不如编译语言好......但更重要的是,我不得不进行一百万次比较,以获得不到百分之三秒的差异。
即使ctype_upper()
完全在&#34;范围内,您每年可节省几秒钟的CPU时间&#34;通过这些其他比较方式,您可以先不必拨打ord()
来获得额外奖励。
寻求可读性。追求可维护性。编写应用程序然后对其进行概要分析,以查看真正瓶颈所在的位置。
答案 1 :(得分:4)
为什么不使用预先构建的php方法ctype_upper
$char = 'A';
echo ctype_upper($char) ? "It's uppercase" : "It's lowercase";
你甚至可以传入一个字符的整数值:
echo ctype_upper($intVal) ? "It's uppercase" : "It's lowercase";
http://php.net/manual/en/function.ctype-upper.php
即使你找到的方法不是比较通过&amp;&amp;或者我粘贴在上面,它将是微秒的差异。你会花费数小时的时间在一年中节省几秒钟。
答案 2 :(得分:1)
来自How to check if an integer is within a range?:
t1_test1 :( $ val&gt; = $ min&amp;&amp; $ val&lt; = $ max):0.3823 ms
t2_test2:(in_array($ val,range($ min,$ max)):9.3301 ms
t3_test3 :( max(min($ var,$ max),$ min)== $ val):0.7272 ms
你也可以使用带有字符的范围(A,B,C ......),但是你认为这不是一个好方法。
答案 3 :(得分:1)
我认为你会通过本土获得最好的结果,但它只会快一点。直接使用ctype_upper
。这是我的测试。
<?php
$numTrials = 500000;
$test = array();
for ($ii = 0; $ii < $numTrials; $ii++) {
$test[] = mt_rand(0, 255);
}
function compare2($intVal) {
return $intVal >= 65 && $intVal <= 90;
}
$tic = microtime(true);
for ($ii = 0; $ii < $numTrials; $ii++) {
$result = compare2($test[$ii]);
}
$toc = microtime(true);
echo "compare2...: " . ($toc - $tic) . "\n";
$tic = microtime(true);
for ($ii = 0; $ii < $numTrials; $ii++) {
$result = ctype_upper($test[$ii]);
}
$toc = microtime(true);
echo "ctype_upper: " . ($toc - $tic) . "\n";
echo "\n";
这给出了一些非常一致的东西:
compare2...: 0.39210104942322
ctype_upper: 0.32374000549316