【问题标题】:Cheating PHP integers欺骗 PHP 整数
【发布时间】:2011-07-27 04:22:20
【问题描述】:

这与我在这里的帖子有关,但方向完全不同 Charset detection in PHP

基本上,我希望减少许多大型数组造成的内存。

这些数组只包含整数,但由于 PHP 在内部使用 32 位和 64 位整数(取决于您为 CPU 类型编译的版本),它会占用内存。

有没有办法欺骗 PHP 使用 8 位或 16 位整数?

我考虑过使用 pack();来完成这个,所以我可以有一个打包的二进制值数组,并在需要时解压它们(是的,我知道这会使其变慢,但比加载然后单独运行每个数组的替代方法要快得多,因为你可以流式传输文本通过,因此它们都需要同时在内存中以保持速度)

您能否提出更好的替代方案来实现这一目标?我知道这很 hacky,但我需要防止巨大的内存激增。

【问题讨论】:

  • 这听起来不像是减少内存使用的明智策略。是什么导致您的脚本激增?你能举一些例子吗?真的有必要一次将那些巨大的数组加载到内存中吗?你拿他们做什么?
  • 稍微有用的提示:如果您想处理大量数字,请忘记 PHP。尝试一些更有效的资源。 (C/C++)
  • 我同意 Pekka 的观点,PHP 已经有很好的内存管理,改变整数的位长不是一个好的解决方案。相反,您应该寻找真正的原因,即巨大的数组本身。如果您能提供有关您正在执行的操作的更多详细信息,我们可能会提供更多帮助。
  • @erenon:没错,但在 PHP 最常用的环境(远程/网络服务器)中,C/C++ 很少是一个简单或可行的选择。
  • PHP 中整数数组的真正问题不是整数位宽,而是数组本身。 PHP 没有。它有字典。如果您想节省内存,请尽可能使用SplFixedArray。否则,您将不得不进行微优化:将您的数组打包成一个字符串,每个使用四个字符来打包一个十六进制字符串。 (在 PHP 中你只能用内存换取速度)。

标签: php


【解决方案1】:

不要告诉任何人!

class IntegerstringArray IMPLEMENTS ArrayAccess {

    var $evil = "0000111122220000ffff";

                 // 16 bit each


    function offsetExists ( $offset ) {
        return (strlen($this->evil) / 4) - 1 >= $offset;
    }

    function offsetGet ( $offset ) {
        return hexdec(substr($this->evil, $offset * 4, 4));
    }

    function offsetSet ( $offset , $value ) {

        $hex = dechex($value);
        if ($fill = 4 - strlen($hex)) {
            $hex = str_repeat("0",  $fill) . $hex;
        }

        for ($i=0; $i<4; $i++) {
            $this->evil[$offset*4+$i] = $hex[$i];
        }
    }

    function offsetUnset ( $offset ) {
        assert(false);
    }

}

所以你几乎可以从这里创建一个数组对象:

$array = new IntegerstringArray();
$array[2] = 65535;
print $array[2];

它在内部存储一个列表并接受 16 位整数。数组偏移量必须是连续的。

未测试。仅作为实施指南。

【讨论】:

  • 哈哈,它正在进入一个开源库,所以不幸的是,我必须告诉:P 我会将它标记为 hack,并为代码中的建议给予应有的信任。再次感谢,这困扰了我 2 个月 :)
  • +1 表示邪恶。还修正了您在测试期间发现的一个错字。
  • @Charles:我会声称这是一个故意的错字,以防止人们实际使用它。但很可惜,这是一个普通的错字:} 谢谢!
  • 我刚刚使用 30,000 次迭代对所有 3 个进行了基准测试。 (16 位 int 的实际大小,我知道最大值约为 32,000)。阵列 - 最快但使用 3.42mb splFixedArray - 非常类似于阵列速度。它们之间的时间为 0.001 秒,但仅使用了 1.69mb。 (超出我的预期。100 万次迭代使用了标准数组大小的 50%) IntegerstringArray - 迄今为止最慢的。比 splFixedArry 慢 10 倍,但使用 measley 0.43mb。这是在 ubuntu 10.10 上的 PHP 5.3.3 的 64 位版本上。我想我会两全其美。用户将能够选择:)
  • 刚刚进行了另一个测试。使用 pack('v') 代替十六进制转换的速度相同,并且将内存进一步减少到 0.38mb。我想我会为用户提供 2 个选项。允许节省内存或允许性能。这将提供两全其美的效果:) 此外,请记住,在所有情况下,获取而不是设置几乎是两倍的速度。数组和 splfixedarray 中为 0.02 秒,integerstringArray 中为 0.22 秒(打包和十六进制转换)。但这也在 for 循环中,因此循环时间会增加。再次感谢所有帮助:D 我终于可以完成项目了:D
猜你喜欢
  • 2019-06-05
  • 2013-06-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多