【问题标题】:Convert array variables to associative array [duplicate]将数组变量转换为关联数组
【发布时间】:2020-04-23 16:31:41
【问题描述】:

在 PHP 中,转换以下数组变量的最快方法是什么:

$id = [11,12,13];
$code = ['1234','5678','9012'];
$qty = [3,4,5];
$amount = [12.34,23.45,34.56];

放入关联数组的数组中,如下所示:

[
  ['id'=>11,'code'=>'1234','qty'=>3,'amount'=>12.34],
  ['id'=>12,'code'=>'5678','qty'=>4,'amount'=>23.45],
  ['id'=>13,'code'=>'9012','qty'=>5,'amount'=>34.56],
]

目前,我正在执行以下操作来转换数据。

$max = count($id);
$data = [];
for ($i=0; $i<$max; $i++) {
  $data[] = [
    'id' => $id[$i],
    'code' => $code[$i],
    'qty' => $qty[$i],
    'amount' => $amount[$i]
  ];
}

我的应用程序经常这样做,并查看是否有办法减少处理时间。
目前使用 PHP 5.6 版

【问题讨论】:

  • 我很确定你拥有的是最快的方法。但是这些值如何最终出现在这些变量中?这可能是让它更快的关键
  • 用户您有几个不同质量的答案。优化的最佳方式是尽早开始优化。正如我之前写的,在您的问题中添加数组如何开始它们的生命。

标签: php arrays


【解决方案1】:

foreach 通常是用于实现所需最终结果的“通用”方法中最快的方法。这是由于在发出 for() 之前调用了 count() 并伴随着一个增量变量来确定要迭代的数组的大小和位置。

基准测试:https://3v4l.org/ejIl5
基准测试1-5000https://3v4l.org/IOlAm

$data = [];
foreach($id as $i => $v) {
    $data[] = [
        'id' => $v,
        'code' => $code[$i],
        'qty' => $qty[$i],
        'amount' => $amount[$i]
    ];
}
//Execution time: ~0.00000200 seconds
$max = count($id);
$data = [];
for ($i=0; $i<$max; $i++) {
  $data[] = [
    'id' => $id[$i],
    'code' => $code[$i],
    'qty' => $qty[$i],
    'amount' => $amount[$i]
  ];
}
//Execution time ~0.00000600 seconds

array_map 最慢

$data = array_map(function($a, $b, $c, $d) {
    return [
        'id' => $a,
        'code' => $b,
        'qty' => $c,
        'amount' => $d
    ];
}, $id, $code, $qty, $amount);
//Execution time: ~0.00001000 seconds

所使用的基准对每种方法都进行了试运行 减少通常会实施的 OP 代码优化问题 在生产环境中。


作为“通用”方法的额外好处,我还运行了双端迭代方法 (for ($i=0; $i&lt;ceil($max/2); $i++)) 的优化版本的基准测试。 https://3v4l.org/KHUul1-5000 https://3v4l.org/Mg95n 在较小的数组大小下具有截然不同的值,范围从 0.00030208 seconds0.00000095 seconds,但平均比一般的 for() 循环慢。

与任何基准测试一样,结果可能会因您的特定环境、设置而异,并且仅用于概括可能的结果。请务必在您的特定环境中对您首选的方法进行基准测试,以确定哪种方法最好。

【讨论】:

  • 感谢您的详细回复。很有帮助。
【解决方案2】:

你也可以使用 foreach。我不确定它会更有效,但它可以帮助你。

    $id = [11,12,13];
    $code = ['1234','5678','9012'];
    $qty = [3,4,5];
    $amount = [12.34,23.45,34.56];
    foreach ($id as $key=>$val)
    {
        $array[$key]["id"]= $val;
        $array[$key]["code"]= $code[$key];
        $array[$key]["qty"]= $qty[$key];
        $array[$key]["amount"]= $amount[$key];
    }

【讨论】:

    【解决方案3】:

    我下面的代码将通过将循环执行减少到一半来优化循环,并给出您预期的结果。

    $id     = [11,12,13,56,34,23,34];
    $code   = ['1234','5678','9012','4343','4543','4642','534'];
    $qty    = [3,4,5,6,7,8,3];
    $amount = [12.34,23.45,34.56,66.34,75.32,54.3,23.2];
    
    
    $max = count($id);
    $loopRun = 0;
    $data = [];
    $halfCount = ceil($max/2);
    for ($i=0; $i < $halfCount; $i++) {
      $loopRun++;
      $data[$i] = [
        'id'        => $id[$i],
        'code'      => $code[$i],
        'qty'       => $qty[$i],
        'amount'    => $amount[$i]
      ];
    
      $data[$max-($i+1)] = [
        'id'        => $id[$max-($i+1)],
        'code'      => $code[$max-($i+1)],
        'qty'       => $qty[$max-($i+1)],
        'amount'    => $amount[$max-($i+1)]
      ];
    }
    echo "Loop Run Count : ".$loopRun."<br>";
    ksort($data);
    

    Demo Link

    【讨论】:

    • 我认为循环迭代的次数根本不是这里的问题;无论您是在一次迭代中处理两个条目还是在每次迭代中处理一个条目,都不会从根本上改变需要处理的条目数量。事实上,您正在使用ksort 添加一个全新的昂贵操作。至少提供一个基准来证明这完全可以使用!
    • @deceze 如果我们将循环减半,运行时间将会减少,例如,如果 1000 次迭代需要 10 秒,那么 500 次迭代只需 5 秒。我们可以只考虑大输入。我已经检查过大量输入,并且我的概念确实对我有用。
    • 用基准证明它!
    • 是的,哇,如果你把所有的实际处理都从循环中取出,那么迭代次数减半的循环肯定会更快……?‍♂️
    • 这段代码根本没有优化。处理的项目数量相同。但是如果计数是 3 会发生什么?您的代码将中断
    猜你喜欢
    • 1970-01-01
    • 2019-01-06
    • 2011-07-11
    • 2017-01-10
    • 2011-05-08
    • 2016-08-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多