有没有比x> = start&& x< =在PHP中结束以测试整数是否在两个整数之间?

时间:2015-10-19 23:15:03

标签: php optimization

这是与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的正常双重比较相比,此函数没有太大改进(可能更慢),但它正是我在尝试优化时开始前进的地方。

4 个答案:

答案 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