php `array_map`与`array_walk`的基准测试

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了php `array_map`与`array_walk`的基准测试相关的知识,希望对你有一定的参考价值。

{
    "name": "potherca/array_walk-vs-array_map",
    "description": "Benchmark for the difference between`array_walk` and `array_map`.",
    "authors": [{"name": "Ben Peachey", "email": "potherca@gmail.com"}],
    "license": "MIT",
    "require": {"phpbench/phpbench": "*"},
    "config": {"bin-dir": "bin"}
}
# Benchmark for `array_map` vs. `array_walk`

## Introduction

As part of [a pull-request](https://github.com/ramsey/uuid/pull/211) written in
PHP I changed a call to `array_map` into call to `array_walk`. This was done
for testing purposes (so part of the call could be mocked) but the question of
performance was raised.

This gist shows the performance difference between  `array_map` and `array_walk`.

For the sake of comparison I've also added a variation using `array_map` and a
callback.

## Conclusion

Regarding speed, in the context of the related code, `array_map` is the fastest:

| subject                   | mean     | diff  |
|---------------------------|----------|-------|
| array_map                 | 50.219μs | 1.00x |
| array_map (with callback) | 55.383μs | 1.10x |
| array_walk                | 56.746μs | 1.13x |


## Details

The benchmark was run using [PhpBench](https://github.com/phpbench/phpbench) and
PHP7.

The benchmark code is attached as a separate file.

### Output

```
 $ php ./bin/phpbench  run ./Benchmark.php  \
       --iterations=15                      \
       --revs=10000                         \
       --retry-threshold=5                  \
       --report='generator: "table", cols: [ "subject", "mean", "diff" ], break: ["benchmark"], sort: {subject: "asc", mean: "desc"}'

PhpBench 0.14.0 (@git_version@). Running benchmarks.

\Potherca\Example\Benchmark

    bench_array_map               R2 I13 P0 	[μ Mo]/r: 50.219 49.996 (μs) 	[μSD μRSD]/r: 1.027μs 2.04%
    bench_array_map_with_callback R1 I12 P0 	[μ Mo]/r: 55.383 55.113 (μs) 	[μSD μRSD]/r: 1.366μs 2.47%
    bench_array_walk              R4 I3 P0 	[μ Mo]/r: 56.746 57.853 (μs) 	[μSD μRSD]/r: 1.660μs 2.93%

3 subjects, 45 iterations, 30,000 revs, 0 rejects, 0 failures, 0 warnings
(best [mean mode] worst) = 48.780 [54.116 54.321] 52.394 (μs)
⅀T: 2,435.219μs μSD/r 1.351μs μRSD/r: 2.479%
benchmark: Benchmark
+-------------------------------+----------+-------+
| subject                       | mean     | diff  |
+-------------------------------+----------+-------+
| bench_array_map               | 50.219μs | 1.00x |
| bench_array_map_with_callback | 55.383μs | 1.10x |
| bench_array_walk              | 56.746μs | 1.13x |
+-------------------------------+----------+-------+

```
<?php

namespace Potherca\Example;

use PhpBench\Benchmark\Metadata\Annotations\ParamProviders;

/**
 * Benchmark the separate `clamp` functions.
 */
class Benchmark
{
    /**
     * @ParamProviders({"provideValues"})
     *
     * @param array $addressPaths
     */
    public function bench_array_map(array $addressPaths)
    {
        $macs = array_map('file_get_contents', $addressPaths);
    }


    /**
     * @ParamProviders({"provideValues"})
     *
     * @param array $addressPaths
     */
    public function bench_array_map_with_callback(array $addressPaths)
    {
        $macs = array_map(function ($addressPath) {
            return file_get_contents($addressPath);
        }, $addressPaths);
    }

    /**
     * @ParamProviders({"provideValues"})
     *
     * @param array $addressPaths
     */
    public function bench_array_walk(array $addressPaths)
    {
        $macs = [];
        array_walk($addressPaths, function ($addressPath) use (&$macs) {
            $macs[] = file_get_contents($addressPath);
        });
    }

    /**
     * @return array[]
     */
    public function provideValues()
    {
        // $addressPaths = glob('/sys/class/net/*/address', GLOB_NOSORT);

        return array(
            array(
                '/sys/class/net/docker0/address',
                '/sys/class/net/enp3s0/address',
                '/sys/class/net/lo/address',
                '/sys/class/net/vboxnet0/address',
                '/sys/class/net/vboxnet1/address',
            )
        );
    }
}

/*EOF*/

以上是关于php `array_map`与`array_walk`的基准测试的主要内容,如果未能解决你的问题,请参考以下文章

php `array_map`与`array_walk`的基准测试

PHP中array_map与array_column之间的关系分析

array_filter与array_map

PHP array_map 一个有趣的函数

如何在 PHP 中使用带有 array_map(...) 的数组?

php [php:array_map()中的call方法] #php