phparraysconcatenationkeyprefix

Fastest way to add a prefix to all array keys?


What is the fastest way to prepend a string to all keys in a flat array?

Input

$array = array(
 '1' => 'val1',
 '2' => 'val2',
);

Needed output:

$array = array(
  'prefix1' => 'val1',
  'prefix2' => 'val2',
);

Solution

  • I've found that PHPBench is not a very good source for non-trivial benchmarks. So unless your actually interested in running for(....); it's not going to correctly show which syntax will be faster. I've put together a simple benchmark to show that foreach is actually the fastest when your use both the key and value during the iteration.

    It's very important to actually force PHP to read the values from a loop iteration, or else it'll do its best to optimize them out. In the example below I use the doNothing function to force PHP to calculate the key and value each time. Using doNothing will cause an overhead to be applied to each loop, but it will be the same for each loop since the number of calls will be the same.

    I wasn't really that surprised that foreach came out on top since it's the language construct for iterating a dictionary.

    $array = range( 0, 1000000 );
    
    function doNothing( $value, $key ) {;}
    
    $t1_start = microtime(true);
    foreach( $array as $key => $value ) {
        doNothing( $value, $key );
    }
    $t1_end = microtime(true);
    
    $t2_start = microtime(true);
    $array_size = count( $array );
    for( $key = 0; $key < $array_size; $key++ ) {
        doNothing( $array[$key], $key );
    }
    $t2_end = microtime(true);
    
        //suggestion from PHPBench as the "fastest" way to iterate an array
    $t3_start = microtime(true);
    $key = array_keys($array);
    $size = sizeOf($key);
    for( $i=0; $i < $size; $i++ ) {
        doNothing( $key[$i], $array[$key[$i]] );
    }
    $t3_end = microtime(true);
    
    $t4_start = microtime(true);
    array_walk( $array, "doNothing" );
    $t4_end = microtime(true);
    
    print
        "Test 1 ".($t1_end - $t1_start)."\n". //Test 1 0.342370986938
        "Test 2 ".($t2_end - $t2_start)."\n". //Test 2 0.369848966599
        "Test 3 ".($t3_end - $t3_start)."\n". //Test 3 0.78616809845
        "Test 4 ".($t4_end - $t4_start)."\n"; //Test 4 0.542922019958
    

    Edit: I'm using PHP 5.3 on 64-bit Mac OSX 10.6