【问题标题】:Filtering posts from a large multi-dimentional array, PHP, Facebook API从大型多维数组、PHP、Facebook API 中过滤帖子
【发布时间】:2012-04-29 11:14:36
【问题描述】:

我需要帮助浏览 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++;
        };

    };

};

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

【问题讨论】:

    标签: php facebook-graph-api iteration facebook-php-sdk


    【解决方案1】:

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

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

    把它放在纤毛状方式 而且应该更快。

    【讨论】:

    • 非常感谢 - 是的,这只是为了描述我的逻辑 - 我知道这是非常低效的代码。我正在使用foreach,然后将使用上面的技术进行优化。再次感谢你的帮助! :)
    【解决方案2】:

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

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

    $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 可能是一个很好的解决方案。

    【讨论】:

    • 非常感谢 - 我将在简化代码时实现这些技术。 :)
    【解决方案3】:

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

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

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

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

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

    【讨论】:

    • 如果您的网站在某些时候处理大量流量,那么使用更高效的代码是否会更好?
    • 当然。但是,与其他机会相比,开发人员每分钟花费的时间所获得的收益可能非常低。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-03-27
    • 1970-01-01
    • 2012-12-04
    • 2018-07-07
    • 2019-11-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多