首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >数组插入时间跳变

数组插入时间跳变
EN

Stack Overflow用户
提问于 2015-05-20 15:35:19
回答 2查看 76关注 0票数 4

在深入研究散列和zval结构以及阵列是如何基于它的基础上,面临着奇怪的插入时间。

下面是一个例子:

代码语言:javascript
运行
复制
$array = array();
$someValueToInsert = 100;
for ($i = 0; $i < 10000; ++$i) {
    $time = microtime(true);
    array_push($array, $someValueToInsert);
    echo $i . " : " . (int)((microtime(true) - $time) * 100000000) . "</br>";
}

所以,我发现每个102420244048.元素将使用更长的时间(>~x10)插入。

这不取决于我将使用array_pusharray_unshift还是简单的$array[] = someValueToInsert

我想在Hash结构中:

代码语言:javascript
运行
复制
typedef struct _hashtable {
   ...
    uint nNumOfElements; 
 ...
} HashTable;

nNumOfElements有缺省最大值,但这并不能解释为什么在特殊计数器中插入需要更多时间(1024,2048.)。

有什么想法吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-05-20 16:18:41

虽然我建议在internals列表中重复检查我的答案,但我相信答案在调整大小()中。当哈希表中需要更多元素时,将调用此函数,并将现有哈希表的大小加倍。因为表从1024开始使用,这个加倍解释了你观察到的结果。代码:

代码语言:javascript
运行
复制
} else if (ht->nTableSize < HT_MAX_SIZE) {  /* Let's double the table size */
    void *old_data = HT_GET_DATA_ADDR(ht);
    Bucket *old_buckets = ht->arData;

    HANDLE_BLOCK_INTERRUPTIONS();
    ht->nTableSize += ht->nTableSize;
    ht->nTableMask = -ht->nTableSize;
    HT_SET_DATA_ADDR(ht, pemalloc(HT_SIZE(ht), ht->u.flags & HASH_FLAG_PERSISTENT));
    memcpy(ht->arData, old_buckets, sizeof(Bucket) * ht->nNumUsed);
    pefree(old_data, ht->u.flags & HASH_FLAG_PERSISTENT);
    zend_hash_rehash(ht);
    HANDLE_UNBLOCK_INTERRUPTIONS();

我不确定remalloc是性能命中,还是重散列是命中,还是整个块是不可中断的。在上面加个分析器会很有趣的。我认为有些人可能已经在PHP 7中这样做了。

附带注意,螺纹安全版本所做的事情有所不同。我不太熟悉这段代码,所以如果您使用ZTS,可能会出现另一个问题。

票数 3
EN

Stack Overflow用户

发布于 2015-05-20 16:15:37

我认为这与动态数组的实现有关。参见“几何展开和摊销成本”数组

To avoid incurring the cost of resizing many times, dynamic arrays resize by a large amount, **such as doubling in size**, and use the reserved space for future expansion

您也可以在这里阅读有关https://nikic.github.io/2011/12/12/How-big-are-PHP-arrays-really-Hint-BIG.html中的数组的内容。

这是动态数组的标准实践。请查看这里,C++动态阵列,增加容量

capacity = capacity * 2; // doubles the capacity of the array

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30354238

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档