【问题标题】:PHP arrays memory usagePHP 数组内存使用情况
【发布时间】:2013-08-13 05:34:00
【问题描述】:

我正在尝试找到一种将大量字符串映射到整数的方法。我使用数组进行了尝试,发现了一种我不理解的行为。当我按字符串(array('someStirng' => 1))索引数组时,它消耗的内存比反之(array(1 =>'someString'))要少。这是否意味着,最好按字符串索引数组并将整数作为大量字符串-整数对的值,或者有什么问题?为什么内存分配差异这么大?

function gen() {
    static $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $randomString = '';
    for ($i = 0; $i < 8; $i++) {
        $randomString .= $characters[rand(0, strlen($characters) - 1)];
    }
    return $randomString;
}

按字符串索引 - 返回 490 KB

$a = array();

for($x = 0;$x < 100000;$x++){
    $a[gen()]  = $x;
}


echo (memory_get_usage() / 1024) . ' KB';

按整数索引 - 返回 10790.2890625 KB(大约是第一种情况的 22 倍,但存储的信息量相同!)

$a = array();

for($x = 0;$x < 100000;$x++){
    $a[$x]  = gen();
}


echo (memory_get_usage() / 1024) . ' KB';

【问题讨论】:

  • 在基准测试中使用rand() 通常不是获得可比结果的秘诀。此外,memory_get_usage() 返回 当前 内存使用情况。当您检查使用情况时,一个急切的垃圾收集器可能已经获取了一些内存。你能在没有rand()memory_get_peak_usage() 的情况下重复实验吗?也许您甚至可以尝试将falsetrue 作为参数来比较实际内存和“仅emalloc”内存。
  • 你能在每个例子的末尾打印出数组的大小吗?您的 gen() 函数可能会生成相同的字符串两次,从而导致该字符串数组索引被覆盖而不是添加新项,这意味着数组更小。
  • 如果你认为 100,000 * 8 字节大约是 780KB,那么很明显memory_get_usage() 函数并没有告诉你你认为它是什么或者这两个数组的大小不是' t 你认为他们是什么。我会花钱买前者。
  • @TomasCreemers 我不认为 rand() 是问题所在。我在这两种情况下都使用 rand() ,但在第二种情况下,当我按整数索引时,它总是分配大约 22 倍的内存量。是的,它可以生成一些字符串两次或更多次,但是有 63^8 种可能的组合,我只生成 100.000 个(出于比较目的,它“只是”63^2.7788)字符串,而且概率太低而无法破坏我的测试结果。 memory_geat_peak_usage() 在两种情况下都返回相同的数字 + 更多 KB

标签: php arrays memory


【解决方案1】:

这个循环

 for ($i = 0; $i < 8; $i++) {

有8次做生意

这个循环在哪里

for($x = 0;$x < 100000;$x++){

再多一点!

现在让我想想问题出在哪里……

编辑

刚刚注意到沙子已经移动了。

使用适合手头任务的任何数据结构。

【讨论】:

    【解决方案2】:

    当我使用您的代码重复您的实验时,我得到 18 072 000 字节的整数索引和 16 471 960 字节的字符串索引。差别不大,这可归因于数组键及其值的不同内存管理。

    使用memory_get_peak_usage(true) 会产生非常相似的结果。计算 for 循环前后的内存使用差异,我得到 18 087 936 字节的整数索引和 16 515 072 字节的字符串索引。

    这是一个很小的差异,可以通过数组键和数组值的不同内部内存管理来解释。也许由于数组键仅限于标量而数组值不是,PHP 可以在某处进行优化。

    在任何情况下,就像@ed-heal 所说的那样,无论你想要做什么,都要使用最好的数据结构。内存使用可能不是那么重要,如果是,PHP 可能不是这项工作的工具。

    【讨论】:

    • 谢谢,但是您是如何获得结果的?为什么他们和我的如此不同?我什至尝试过 memory_get_peak_usage(true),但结果和以前一样,只是四舍五入到 2 的幂
    • 当我在 codepad.org/vwhCDVSf 上测试您的代码(memory_get_usage() 与您的代码完全相同)时,我得到 9150.54296875 KB 的整数键和 7978.8125 KB 的字符串键。使用 memory_get_peak_usage(true) 我得到 9216 KB 的整数键和 8192 KB 的字符串键。我真的无法重现您观察到的巨大差异。
    • 好吧,至少在未来我会知道我的本地服务器不能很好地使用 PHP 内存使用函数。 (Win XP + XAMPP)
    • 也许 XAMPP 安装了旧的 PHP 版本或奇怪的配置?如果您对内存使用感兴趣,您可能想与从php.net 下载的版本进行比较。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-19
    • 1970-01-01
    • 1970-01-01
    • 2020-12-19
    • 2012-07-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多