【问题标题】:How to best add element to array at arbitrary index in PHP?如何最好地将元素添加到 PHP 中任意索引处的数组?
【发布时间】:2013-04-04 08:41:29
【问题描述】:

如何编写一个解决方案,让当前的 PHP 解释器 (5.4) 足够智能,只需执行大约 3-5 个副本而不是完整的逐项数组排序?

注意,我知道一些将元素插入索引数组的方法。然而这并不能满足我的理解。例如在 C++ 中,您可以使用 std::copy 或将 struct 或 union 作为多元素数组游标来执行某些操作。

所以我想知道我是否以某种方式遵守 PHP 的规则,可以使用什么样的语法来拥有,在引擎盖下,更接近于

将[range元素从some index复制到A的末尾]到临时C

将B复制到A[索引],

将C复制到A[Index+count(B)]

比这个...

$MasterItemList = $Page[$CurrentPage]->GetItems();   /* Returns an array with 512 Items.         */
$UpdateList = GetUpdatePage();                       /* Returns multi-dimensional array such that: 
                                                        $result[][0]=an index and 
                                                        $result[][1]=a list of items             */

foreach($UpdateList as $Update)
{ foreach($Update as $cursor => $ItemList)
  {
    $cursor=$cursor+0;  //to int..
    $numitems=count($ItemList);

    if($ItemList[0]->NewAddition)
    {
      $BeforeUpdate=array_splice($MasterItemList,0, $cursor, true);
      $AfterUpdate=array_splice($MasterItemList, $cursor+$numitems, 0);
      $MasterItemList=array_merge($BeforeUpdate,$ItemList,$AfterUpdate);

      $Page[$CurrentPage]->OffsetCorrection+=$numitems;
    }
    else
    {
      $i=0;
      foreach($ItemList as $LineItem)
      {
        $MasterItemList[$cursor+$i] = $LineItem;
        $i++;
      }
    }
  }
}

如果我记下来有一些错误,请原谅我,让我知道,我会纠正它们。

也就是说,我认为解释器无法使用正确的引用和范围,以便能够直接使用此方法执行逻辑。它已经是一个看起来非常昂贵的东西了.. 可以做些什么来为 PHP 做这个“正确的方法”?

示例:

// An Update List

Array(
    [0] => Array(
        [0] => 31
        [1] => Array(
            [1] => stdClass Object 
                (
                    [NewAddition] => false
                    [Name] => "********"
                    [Date] => 1364920943
                    [Active] => 1
                    .
                    .
                    .
                )

            [2] => stdClass Object 
                (
                    [NewAddition] => false
                    [Name] => "********"
                    [Date] => 1364920943
                    [Active] => 1
                    .
                    .
                    .
                )

            [3] => stdClass Object 
                (
                    [NewAddition] => false
                    [Name] => "********"
                    [Date] => 1364920943
                    [Active] => 1
                    .
                    .
                    .
                )

        )                
    )
)

MasterItemList 只是这些相同对象的数组 (class Item)。

需要注意的几点:

  • 此数据只能以纯顺序的方式访问,任何对这个脚本有影响的地方。
  • 只有新插入的集合中的第一项需要在这部分脚本中检查更新。套装中的所有物品都将始终是新的。
  • 超过 512 的项目会自动调整到下一页加载。我可以调整页面大小以在数组排序性能和数据获取性能(异步缓冲)之间进行权衡。

【问题讨论】:

  • 您能否为$MasterItemList$UpdateList 添加一个小数据样本。
  • @Tigger - 当然,你的意思是像 print_r 之类的样本数据吗?
  • 是的,就像print_r(),但请查看下面@Jon 的答案。
  • 您有一个包含 512 个键的数组。唯一更快的是根本没有数组。 512键不算什么。你期待什么样的改进?从 0.003 秒到 0.029 秒?
  • 我正在寻找以某种方式直接从数组中拼接一个范围。例如,仅使用元素 128-256 的值创建一个新数组,而不进行完整的数组排序。我想复制范围而不是每个单独的值

标签: php arrays performance interpreter


【解决方案1】:

首先,PHP 数组不是数据结构意义上的“数组”;它们实际上是将哈希表和双向链表合二为一。当您索引到数组时,例如与$list[$i] $i 进行散列以找到对应的元素;这不是简单的算术,例如C++。

此外,由于数组也是链表,所以array_splice 的实现比看起来要高效得多,至少如果要删除的部分足够小(散列新项目通常很快,并且在链表的某个地方是常数时间)。

当然,这意味着 PHP 数组比“纯”数组消耗更多的内存,而且如果您只打算进行基于索引的访问,它们也会更慢。在这些情况下,SPL 提供了SplFixedArray,它是数据结构意义上的数组实现。

在您的特定情况下,array_splice 应该是您的首选;您只需一次调用即可插入一个数组块:

array_splice($MasterItemList, $cursor, 0, $ItemList);

【讨论】:

  • 您好,感谢您提供有关 SplFixedArray 的信息,现在开始阅读。我知道一些关于 PHP 不使用直接数组的知识,但并不多。你提到的一件衬里让我想起了我忘记的事情。我知道我错过了什么!请查看我为预期用途编辑 $AfterUpdate= 行的位置。 (保留尾随元素并在给定点插入)
猜你喜欢
  • 2012-07-23
  • 2016-01-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-19
  • 2014-11-13
  • 1970-01-01
相关资源
最近更新 更多