【发布时间】: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()的情况下重复实验吗?也许您甚至可以尝试将false和true作为参数来比较实际内存和“仅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