1

我需要帮助通过 Facebook PHP SDK 返回的大型数组。我正在尝试查找用户的所有帖子,然后还要检查帖子是否包含/不包含“链接”键。我已经读到,由于复制 1MB+ 的数据来处理它,在这种大小的数组上使用 foreach 循环效率很低。我应该如何有效地遍历信息?

数组的结构是这样的,其中“x”是每个帖子的数量:

Array
(
    [data] => Array
        (
            [x] => Array
                (
                    [from] => Array
                        (
                            [name] => james
                        )

                    [message] => Thanks for the great interview! 
                    [link] => http://example.com/link.html
                    [description] => Description here
                    [etc] => Various other keys possible
                )
        )
)

然后我当前的代码如下所示,其中 $feed 是来自 Facebook API 的数组:

for ($x=0, $y=0; $x<=1000, $y<=19; $x++) {

    if (array_key_exists('james', $feed['data'][$x]['from']['name'])) {

        if (!array_key_exists('link', $feed['data'][$x])) {

            echo "<div>" . $feed['data'][$x]['message'] . "<hr>" . $feed['data'][$x]['description'] . "</div>";

            $y++;
        };

    };

};

我已经阅读了各种迭代器,但我不知道该使用哪个!希望你能帮助我,干杯,乔

4

3 回答 3

1

您是正确的,foreach因为在迭代大型数组时可能会很慢,因为默认情况下它使用值的副本,就像您提到的那样,复制会消耗内存并需要一些时间。

但是,使用 foreach 的另一种方法是通过引用,它不会创建副本。它适用于原始值。这意味着无论数组大小,它都不会再次放入内存中。这是另一个 StackOverflow 用户共享foreach 引用示例:

$a = array('hello', 'world');
$asRef =& $a;
$ontime = 0;
foreach($asRef as $i => $v)
{
   if (!$ontime++) $a = array('hash', 'the cat');
   echo " $i: $v\n";
}

您可以选择使用 SPL 中的ArrayIterator,它是用 C 语言编写的,速度非常快。只是一个如何工作的简单示例:

// This would be your large facebook array
$big_array = array(1,2,3,...,10000,10001);

// Get the iterator object
$array_iterator = new ArrayIterator($big_array);

foreach($array_iterator as $item)
{
   //Do something with $item here
}

我没有做任何基准测试,但我想通过引用传递数组并使用 ArrayIterator 可能是一个很好的解决方案。

于 2012-04-29T12:01:02.573 回答
1

谈到 foreach 性能并实际上使用 array_key_exists 是没有意义的,恕我直言,这要好得多

foreach($feed['data'] as $post){
           if($post['from']['name']==='youruser'){
            //has user
           }
          if(isset($post['link'])){
            //has link
          }
}     

把它放在纤毛的方式,它应该更快。

于 2012-04-29T12:20:20.907 回答
-1

foreach 并不总是复制。当它复制时,它只复制被迭代的直接数据结构;它不会复制任何值。例如,如果你做了

foreach ($arr['data'] as $k => $v) ....

如果有 100 个子元素(您将一个缩写为 [x] ),那么它将创建一个数组,复制这 100 个键,但不会复制键指向的值,这些值是子数组/树。在内部它只存储一个指针并让它指向子数组的内存地址,而不需要复制。

我认为您白做大事,因为实际复制的数据量很少。foreach 几乎总是非常非常快......

如果您想一睹为快,请查看循环前后的memory_get_usage () 和memory_get_peak_usage ()。

于 2012-04-29T14:47:35.220 回答