php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #53242 count() slow for global / static arrays
Submitted: 2010-11-04 17:50 UTC Modified: 2010-11-05 02:40 UTC
From: einars at gmail dot com Assigned:
Status: Not a bug Package: Performance problem
PHP Version: 5.3.3 OS: Arch Linux
Private report: No CVE-ID: None
 [2010-11-04 17:50 UTC] einars at gmail dot com
Description:
------------
When the arrays are defined global or static, the sizeof() / count method suddenly gets very slow.


Test script:
---------------
<?php
$items = range(0, 50000);
$times = 200;

$time = microtime(true);
for ($i = 0; $i < $times; $i++) {
    $foo = sizeof($items);
}
printf("Non-global access: %.2fs\n", microtime(true) - $time);

$time = microtime(true);
for ($i = 0; $i < $times; $i++) {
    test_global();
}
printf("Global access: %.2fs\n", microtime(true) - $time);

function test_global() {
    global $items;
    $foo = sizeof($items);
}


Expected result:
----------------
% php array-test.php
Non-global access: 0.00s
Global access: 0.00s


Actual result:
--------------
% php array-test.php
Non-global access: 0.00s
Global access: 2.73s


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2010-11-05 02:40 UTC] cataphract@php.net
-Status: Open +Status: Bogus
 [2010-11-05 02:40 UTC] cataphract@php.net
To be expected.

When you do global $items; the underlying zval has its refcount incremented to 2 since now it's referred to by the global symbol $items and the local symbol $items and the is_ref flag is set.

Since sizeof does not receive its argument by reference and you're giving it an is_ref zval, a separation is forced and the value if copied. Since $items refers to a big variable (50k+ items), the performance penalty is big.

To cut the story short: use $foo = $GLOBALS['items'].
 [2010-12-01 17:58 UTC] ceo at l-i-e dot com
Call me crazy, but once you declare it global in the function, having a local one seems kind of silly...

Why not just have the one zval?...

From a guy who knows very little of php internals, but can't figure out the purpose of a "local" $items when it's been declared global in the function body.

And "static" should be its own zval, not interacting in any way shape or form with any zval in any other scope...  So it should have a refcount < 2 as well...
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Mar 28 20:01:28 2024 UTC