---
title: 'SplFixedArray vs Array, array_map vs foreach'
url: 'https://johnlinhart.com/blog/splfixedarray-vs-array-array_map-vs-foreach'
markdown: 'https://johnlinhart.com/blog/splfixedarray-vs-array-array_map-vs-foreach.md'
date: '2023-03-26'
description: "In my previous benchmark post about the splat operator the array_map function was very slow compared to foreach. I've read a great deal that the SplFixedArray is fast and memory efficient over classic PHP array. I wanted to test it with the thought that I can't seem to get out of my head lately: ho…"
taxonomy:
  archives_month:
    - mar_2023
  archives_year:
    - '2023'
---

# SplFixedArray vs Array, array_map vs foreach

[ Blog ](https://johnlinhart.com/)      SplFixedArray vs Array, array\_map vs foreach    

   26 *Mar*   
#### [SplFixedArray vs Array, array\_map vs foreach](https://johnlinhart.com/blog/splfixedarray-vs-array-array_map-vs-foreach)

In my [previous benchmark post](https://johnlinhart.com/blog/php-splat-operator-for-array-type-hints) about the splat operator the [array\_map](https://www.php.net/manual/en/function.array-map.php "This link will take you to an external web site. We are not responsible for their content.") function was very slow compared to `foreach`. I've read a great deal that the [SplFixedArray](https://www.php.net/manual/en/class.splfixedarray.php "This link will take you to an external web site. We are not responsible for their content.") is fast and memory efficient over classic PHP array. I wanted to test it with the thought that I can't seem to get out of my head lately: *how to create a smart collection in PHP*.

I've created simple class with 2 map method implementation. `mapMap` is using the `array_map` function and the `foreachMap` method is emulating the same functionality with `foreach`.Here is the benchmark script:

```php
<?php

class MapCollection
{
    private $items;

    public function __construct(array $items)
    {
        $this->items = $items;
    }

    public function mapMap(callable $callable): self
    {
        return new self(array_map($callable, $this->items));
    }

    public function foreachMap(callable $callable): self
    {
        $changes = [];

        foreach ($this->items as $key => $item) {
            $changes[$key] = $callable($item);
        }

        return new self($changes);
    }
}

class SplMapCollection extends \SplFixedArray
{
    public function __construct(array $items)
    {
        parent::__construct(count($items));

        foreach ($items as $key => $item) {
            parent::offsetSet($key, $item);
        }
    }

    public function mapMap(callable $callable): self
    {
        return new self(array_map($callable, $this->toArray()));
    }

    public function foreachMap(callable $callable): self
    {
        $changes = [];

        foreach ($this->toArray() as $key => $item) {
            $changes[$key] = $callable($item);
        }

        return new self($changes);
    }
}

$input = [];

for ($i = 0; $i < 1000000; $i++) {
    $input[] = $i;
}

$callable = function (int $item) {
    return $item++;
};

$time          = microtime(true);
$memory        = memory_get_usage(true);
$mapCollection = new MapCollection($input);

writeResults('MapCollection::__construct', $time, $memory);

$time   = microtime(true);
$memory = memory_get_usage(true);
$mapMap = $mapCollection->mapMap($callable);

writeResults('MapCollection::mapMap', $time, $memory);

$time   = microtime(true);
$memory = memory_get_usage(true);
$mapMap = $mapCollection->foreachMap($callable);

writeResults('MapCollection::foreachMap', $time, $memory);

$time             = microtime(true);
$memory           = memory_get_usage(true);
$splMapCollection = new SplMapCollection($input);

writeResults('splMapCollection::__construct', $time, $memory);

$time   = microtime(true);
$memory = memory_get_usage(true);
$mapMap = $splMapCollection->mapMap($callable);

writeResults('splMapCollection::mapMap', $time, $memory);

$time   = microtime(true);
$memory = memory_get_usage(true);
$mapMap = $splMapCollection->foreachMap($callable);

writeResults('splMapCollection::foreachMap', $time, $memory);

function writeResults(string $class, float $time, float $memory): void
{
    $timeUsage = microtime(true) - $time;
    $memoryUsage = memory_get_usage(true) - $memory;
    echo "{$class} processed in {$timeUsage} ms and used {$memoryUsage} \n\n";
}
```

And here are the results:

```
MapCollection::__construct processed in 0.00011277198791504 ms and used 0 

MapCollection::mapMap processed in 1.0667450428009 ms and used 33558528 

MapCollection::foreachMap processed in 1.4232130050659 ms and used 0 

splMapCollection::__construct processed in 0.94543695449829 ms and used 16003072 

splMapCollection::mapMap processed in 2.1207430362701 ms and used -17555456 

splMapCollection::foreachMap processed in 2.3400418758392 ms and used 0 
```

### Conclusion

#### array\_map vs foreach

`array_map` was way slower in my splat operator post because it creates a new array. `Foreach` was just modifying the existing array. If I emulate the same functionality with `foreach` where a new array is created, `foreach` is slightly slower. In the previous post I stated that I will think twice to use `array_map` again. If it's used for the use case is was designed for then it's the best option.

#### Array vs SplFixedArray

I must be using it wrong. SplFixedArray is way slower compared to just Array. I'll stick with array until I find a good use case or learn how to use SplFixedArray properly.

 [ Next Post](https://johnlinhart.com/blog/cronfig-is-dumb) [Previous Post ](https://johnlinhart.com/blog/install-mautic-via-composer)

#### Projects I'm part of

 **[Mautic](http://mautic.org)** Open source marketing automation software.
 **[Calculoid.com](http://calculoid.com)** Web app which lets you create a calculator.
 **[eScope.cz](http://escope.cz/en)** My Joomla! articles and extensions.
 **[CRMery](http://crmery.com)** CRM as Joomla component.
 **[Constimator.com](http://constimator.com)** Web app which lets you calculate cost of building. 

#### For stalkers

 [](https://github.com/escopecz "GitHub") [](https://twitter.com/jan_linhart "Twitter") [](http://stackoverflow.com/users/2421302/escopecz "Stack Overflow") [](https://cz.linkedin.com/pub/jan-linhart/52/a03/80a "LinkedIn") [](http://magazine.joomla.org/component/k2/itemlist/user/5517-janlinhart "Joomla Magazine") 

#### Popular Tags

  [mautic](https://johnlinhart.com/tag:mautic) [developer](https://johnlinhart.com/tag:developer) [technology](https://johnlinhart.com/tag:technology) [web development](https://johnlinhart.com/tag:web%20development) [notes](https://johnlinhart.com/tag:notes) [composer](https://johnlinhart.com/tag:composer) [marketing](https://johnlinhart.com/tag:marketing) [personal](https://johnlinhart.com/tag:personal) [cronfig](https://johnlinhart.com/tag:cronfig) [hobby](https://johnlinhart.com/tag:hobby) [webexpo](https://johnlinhart.com/tag:webexpo) [freelance](https://johnlinhart.com/tag:freelance) [cost](https://johnlinhart.com/tag:cost) [calculator](https://johnlinhart.com/tag:calculator) [rate](https://johnlinhart.com/tag:rate) [calculoid](https://johnlinhart.com/tag:calculoid) [wordpress](https://johnlinhart.com/tag:wordpress) [grav](https://johnlinhart.com/tag:grav) [pagekit](https://johnlinhart.com/tag:pagekit) [cms](https://johnlinhart.com/tag:cms) [john](https://johnlinhart.com/tag:john) [name](https://johnlinhart.com/tag:name) 

#### Archives

- [ 1 November 2024  ](https://johnlinhart.com/blog/archives_month:nov_2024)
- [ 1 October 2024  ](https://johnlinhart.com/blog/archives_month:oct_2024)
- [ 5 March 2023  ](https://johnlinhart.com/blog/archives_month:mar_2023)
- [ 1 January 2020  ](https://johnlinhart.com/blog/archives_month:jan_2020)
- [ 2 December 2019  ](https://johnlinhart.com/blog/archives_month:dec_2019)
- [ 1 September 2019  ](https://johnlinhart.com/blog/archives_month:sep_2019)
- [ 1 August 2018  ](https://johnlinhart.com/blog/archives_month:aug_2018)
- [ 1 November 2016  ](https://johnlinhart.com/blog/archives_month:nov_2016)
- [ 1 September 2015  ](https://johnlinhart.com/blog/archives_month:sep_2015)
- [ 1 June 2015  ](https://johnlinhart.com/blog/archives_month:jun_2015)
- [ 1 May 2015  ](https://johnlinhart.com/blog/archives_month:may_2015)
- [ 1 April 2015  ](https://johnlinhart.com/blog/archives_month:apr_2015)

#### Syndicate

 [ Atom 1.0](https://johnlinhart.com/blog.atom) [ RSS](https://johnlinhart.com/blog.rss)

---

## Navigation

- Parent: [Blog](https://johnlinhart.com/index.md)
- Previous: [Cronfig is dumb and difficult to configure](https://johnlinhart.com/blog/cronfig-is-dumb.md)
- Next: [Install Mautic via Composer](https://johnlinhart.com/blog/install-mautic-via-composer.md)
