Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/294.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
我如何优化这个循环以在PHP上快速运行。在javascript上运行非常快_Javascript_Php_Loops_For Loop - Fatal编程技术网

我如何优化这个循环以在PHP上快速运行。在javascript上运行非常快

我如何优化这个循环以在PHP上快速运行。在javascript上运行非常快,javascript,php,loops,for-loop,Javascript,Php,Loops,For Loop,因此,我一直在将一些代码从Javascript移植到PHP,现在可以工作了,但是,执行时间非常差。在PHP中大约需要26秒,而在javascript中速度非常快。我已经能够将其分解为导致问题的for循环。这是循环 for ($R0d = 0; $R0d < $F0d; $R0d = $R0d + 16) { $f0d = [bitwise_and(JS_charCodeAt($C0d,($R0d + 4)), 0xff) | shift_left_32((b

因此,我一直在将一些代码从Javascript移植到PHP,现在可以工作了,但是,执行时间非常差。在PHP中大约需要26秒,而在javascript中速度非常快。我已经能够将其分解为导致问题的for循环。这是循环

for ($R0d = 0; $R0d < $F0d; $R0d = $R0d + 16) {
                $f0d = [bitwise_and(JS_charCodeAt($C0d,($R0d + 4)), 0xff) | shift_left_32((bitwise_and(JS_charCodeAt($C0d, ($R0d + 5)), 0xff)), 8) | shift_left_32((bitwise_and(JS_charCodeAt($C0d, ($R0d + 6)), 255)), 16) | shift_left_32((bitwise_and(JS_charCodeAt($C0d, ($R0d + 7)), 255)), 24), bitwise_and(JS_charCodeAt($C0d, ($R0d)), 255) | shift_left_32((bitwise_and(JS_charCodeAt($C0d, ($R0d + 1)), 255)), 8) | shift_left_32((bitwise_and(JS_charCodeAt($C0d, ($R0d + 2)), 255)), 16) | shift_left_32((bitwise_and(JS_charCodeAt($C0d, ($R0d + 3)), 0xff)), 24)];

$H0d = [bitwise_and(JS_charCodeAt($C0d, ($R0d + 12)), 255) | shift_left_32((bitwise_and(JS_charCodeAt($C0d, ($R0d + 13)), 255)), 8) | shift_left_32((bitwise_and(JS_charCodeAt($C0d, ($R0d + 14)), 255)), 16) | shift_left_32((bitwise_and(JS_charCodeAt($C0d, ($R0d + 15)), 255)), 24), bitwise_and(JS_charCodeAt($C0d, ($R0d + 8)), 255) | shift_left_32((bitwise_and(JS_charCodeAt($C0d, ($R0d + 9)), 255)), 8) | shift_left_32((bitwise_and(JS_charCodeAt($C0d, ($R0d + 10)), 255)), 16) | shift_left_32((bitwise_and(JS_charCodeAt($C0d, ($R0d + 11)), 255)), 24)];

                $f0d = x64Multiply($f0d, $M0d);
                $f0d = x64Rotl($f0d, 31);
                $f0d = x64Multiply($f0d, $I0d);
                $P0d = x64Xor($P0d, $f0d);
                $P0d = x64Rotl($P0d, 27);
                $P0d = x64Add($P0d, $o0d);
                $P0d = x64Add(x64Multiply($P0d, [0, 5]), [0, 1390208809]);
                $H0d = x64Multiply($H0d, $I0d);
                $H0d = x64Rotl($H0d, 33);
                $H0d = x64Multiply($H0d, $M0d);
                $o0d = x64Xor($o0d, $H0d);
                $o0d = x64Rotl($o0d, 31);
                $o0d = x64Add($o0d, $P0d);
                $o0d = x64Add(x64Multiply($o0d, [0, 5]), [0, 944331445]);       
            }
我正在使用此篮球图像的base64代码测试此哈希的实现:

哈希包含字符串的开头,包括mime类型 所以这将导致存储的值为:
data:image/jpeg;base64,[base64编码字符串]

我从这个网站上得到了base64数据
然后,我将该值存储在名为
$testValue
的变量中,并运行以下函数调用
$output=x64hash128($testValue,31)导致值c5aed78543b2b31c233fa4289e0eadfa

您的主要问题是JS_charCodeAt函数编写错误。随着输入大小的增加,性能呈指数级下降,因为每次对单个字符调用此函数时,它都会转换UTF8-UTF16中的整个输入

添加这个简单的缓存将工作时间减少了100倍。只需替换此功能:

function JS_charCodeAt($str, $index) {
    static $utf16s = [];
    if (isset($utf16s[$str]))
        $utf16 = $utf16s[$str];
    else
        $utf16s[$str] = $utf16 = mb_convert_encoding($str, 'UTF-16LE', 'UTF-8');
    return ord($utf16[$index*2]) + (ord($utf16[$index*2+1]) << 8);
}
函数JS_charCodeAt($str,$index){ 静态$utf16s=[]; 如果(isset($utf16s[$str])) $utf16=$utf16s[$str]; 其他的 $utf16s[$str]=$utf16=mb_convert_编码($str,'UTF-16LE','UTF-8'); 返回ORD太长了,读不下去了(OutF16[$index 2)+(ORD($utf16[$index 2 ++] 1)tl;如果这是MurmurHash,那么去看看。 否则,您可以摆脱大量不必要的函数调用,如下所示:

for ($i = 0; $i < $F0d; $i += 16) {
    // Let's start with this block. What does it do? It clearly takes a block of 8 bytes
    // four at a time, and builds a pair of 32-bit words.
    // Each byte is AND-ed bitwise with 0xFF to ensure it is a 8-bit value.
    $f0d = [
        bitwise_and(JS_charCodeAt($C0d, ($i + 4)), 0xff)
        | shift_left_32((bitwise_and(JS_charCodeAt($C0d, ($i + 5)), 0xff)), 8)
        | shift_left_32((bitwise_and(JS_charCodeAt($C0d, ($i + 6)), 255)), 16)
        | shift_left_32((bitwise_and(JS_charCodeAt($C0d, ($i + 7)), 255)), 24),
        bitwise_and(JS_charCodeAt($C0d, ($i)), 255)
        | shift_left_32((bitwise_and(JS_charCodeAt($C0d, ($i + 1)), 255)), 8)
        | shift_left_32((bitwise_and(JS_charCodeAt($C0d, ($i + 2)), 255)), 16)
        | shift_left_32((bitwise_and(JS_charCodeAt($C0d, ($i + 3)), 0xff)), 24),
    ];
    // We can do the same thing in PHP using the unpack() function and type V on an appropriate substr() of $C0d.
    // But due to the vagaries of unpack() and the fact that the elements are reversed,
    // we cannot use unpack alone (well, we COULD, if we changed the algorithm below, but it would be too awkward).
    $x0d = array_reverse(array_values(unpack('V2', substr($C0d, $i, 8))));

    // If you now dump $f0d and $x0d, they should be identical.
    // You can do the same with $H0d. 

    // Actually you can do both together, avoiding the array manipulation, BUT I HAVEN'T CHECKED (just do a simple test run and verify $x0d's contents comparing it to $f0d and $H0d's):

    $x0d = unpack('V4', substr($C0d, $i, 16));
    $f0d = [ $x0d[2], $x0d[1] ];
    $H0d = [ $x0d[4], $x0d[3] ];

    // and get all 16 bytes neatly converted in two two-32-bit word arrays.
($i=0;$i<$F0d;$i+=16)的
{
//让我们从这个块开始。它做什么?它显然需要一个8字节的块
//一次四个,并构建一对32位字。
//每个字节都使用0xFF按位和按位进行编码,以确保其为8位值。
$f0d=[
按位_和(JS_charCodeAt($C0d,($i+4)),0xff)
|左移位32((按位)和(JS_charCodeAt($C0d,($i+5)),0xff)),8)
|左移位32((按位移位)和(按位移位($C0d,($i+6)),255)),16)
|左移位32((按位移位)和(按位移位($C0d,($i+7)),255)),24),
按位_和(JS_charCodeAt($C0d,($i)),255)
|左移位32((按位移位)和(按位移位($C0d,($i+1)),255)),8)
|左移位32((按位移位)和(按位移位($C0d,($i+2)),255)),16)
|左移位32((按位移位)和(按位移位($C0d,($i+3)),0xff)),24),
];
//我们可以在PHP中使用unpack()函数并在$C0d的适当substr()上键入V来执行相同的操作。
//但是由于unpack()的变幻莫测和元素颠倒的事实,
//我们不能单独使用unpack(好吧,我们可以,如果我们改变下面的算法,但是这太尴尬了)。
$x0d=array_reverse(数组_值(unpack('V2',substr($C0d,$i,8)));
//如果现在转储$f0d和$x0d,它们应该是相同的。
//您可以使用$H0d执行同样的操作。
//实际上,您可以同时执行这两项操作,避免数组操作,但我没有检查(只需执行一个简单的测试运行,并将$x0d的内容与$f0d和$H0d的内容进行比较):
$x0d=unpack('V4',substr($C0d,$i,16));
$f0d=[$x0d[2],$x0d[1];
$H0d=[$x0d[4],$x0d[3];
//并将所有16个字节整齐地转换为两个32位字数组。

你能给我整个文件吗,这样我就可以运行它并为你进行优化了?我不认为这个问题只是你发送到这里的一部分。但我关注的是PHP性能,所以我打赌我可以大大降低它。函数调用很昂贵,使用本机数据类型和算术运算符。无论如何,可能只是内联函数和使用本机操作相反,它们中的大多数都能做到这一点。这种节奏中的函数调用非常昂贵。这同样适用于[0,5]行中的数组构造等等,您至少应该将其扩展到属性,或者直接内联。好的,一旦我回到联机状态,很快就会发布更多代码。我使用函数调用的唯一原因是,我需要值为32位,就像复制我想要的相同输出所需的Javascript一样。这些函数确保整数值为32位,而不是64位PHP一直在做什么。我知道,但你可以通过在计算后添加&0xFFFFFFFF来实现。不需要函数。原因是,JS速度快得多可能是因为浏览器有智能优化器和JIT,它们为你内联并转换为本机代码。PHP还没有实现,函数调用很昂贵,甚至更昂贵我必须使用函数而不是本机操作。一旦您发布整个工作代码以在本地进行测试,我将研究它。
for ($i = 0; $i < $F0d; $i += 16) {
    // Let's start with this block. What does it do? It clearly takes a block of 8 bytes
    // four at a time, and builds a pair of 32-bit words.
    // Each byte is AND-ed bitwise with 0xFF to ensure it is a 8-bit value.
    $f0d = [
        bitwise_and(JS_charCodeAt($C0d, ($i + 4)), 0xff)
        | shift_left_32((bitwise_and(JS_charCodeAt($C0d, ($i + 5)), 0xff)), 8)
        | shift_left_32((bitwise_and(JS_charCodeAt($C0d, ($i + 6)), 255)), 16)
        | shift_left_32((bitwise_and(JS_charCodeAt($C0d, ($i + 7)), 255)), 24),
        bitwise_and(JS_charCodeAt($C0d, ($i)), 255)
        | shift_left_32((bitwise_and(JS_charCodeAt($C0d, ($i + 1)), 255)), 8)
        | shift_left_32((bitwise_and(JS_charCodeAt($C0d, ($i + 2)), 255)), 16)
        | shift_left_32((bitwise_and(JS_charCodeAt($C0d, ($i + 3)), 0xff)), 24),
    ];
    // We can do the same thing in PHP using the unpack() function and type V on an appropriate substr() of $C0d.
    // But due to the vagaries of unpack() and the fact that the elements are reversed,
    // we cannot use unpack alone (well, we COULD, if we changed the algorithm below, but it would be too awkward).
    $x0d = array_reverse(array_values(unpack('V2', substr($C0d, $i, 8))));

    // If you now dump $f0d and $x0d, they should be identical.
    // You can do the same with $H0d. 

    // Actually you can do both together, avoiding the array manipulation, BUT I HAVEN'T CHECKED (just do a simple test run and verify $x0d's contents comparing it to $f0d and $H0d's):

    $x0d = unpack('V4', substr($C0d, $i, 16));
    $f0d = [ $x0d[2], $x0d[1] ];
    $H0d = [ $x0d[4], $x0d[3] ];

    // and get all 16 bytes neatly converted in two two-32-bit word arrays.