因为它似乎没有人做过这之前,我认为这是一个好主意,以供参考。我已经走过,通过基准或代码撇去来表征array_ *函数。我试图把更有趣的Big-O靠近顶部。此列表不完整。
注意:所有的Big-O,假设散列查找是O(1),即使它真的是O(n)。 n的系数如此之低,存储足够大的数组的RAM开销将在查找Big-O的特性开始起作用之前伤害你。例如,在N = 1和N = 1,000,000的对array_key_exists的调用之间的差异是〜50%的时间增加。
有趣点:
> isset / array_key_exists比in_array和array_search要快得多
>(union)比array_merge快一点(看起来更好)。但它的工作方式不同,所以记住。
> shuffle与array_rand在同一个Big-O层上
> array_pop / array_push比array_shift / array_unshift快,因为重新索引惩罚
查找:
array_key_exists O(n)但真的接近O(1) – 这是因为在碰撞中的线性轮询,但是因为碰撞的机会很小,所以系数也很小。我发现你把散列查找作为O(1)给一个更逼真的大O。例如,N = 1000和N = 100000之间的差异仅为大约50%的减速。
isset($ array [$ index])O(n)但真的接近O(1) – 它使用与array_key_exists相同的查找。由于它是语言构造,如果密钥被硬编码,将缓存查找,导致在重复使用相同密钥的情况下的加速。
in_array O(n) – 这是因为它通过数组进行线性搜索,直到找到该值。
array_search O(n) – 它使用与in_array相同的核心函数,但返回值。
队列功能:
array_push O(Σvar_i,for all i)
array_pop O(1)
array_shift O(n) – 它必须重新索引所有的键
array_unshift O(nΣvar_i,对于所有i) – 它必须重新索引所有的键
阵列交叉,联合,减法:
array_intersect_key如果交集0%与O交叉(对于所有i),则交叉100%do O(对于所有i,Max(param_i_size)*Σparam_i_count)
array_intersect如果交集100%do O(n ^ 2 *Σparam_i_count,对于所有i),如果交集0%与O交叉(n ^ 2)
array_intersect_assoc如果交集100%do O(Max(param_i_size)*Σparam_i_count,for all i),如果交集0%与O相交(Σparam_i_size,对于所有i)
array_diff O(πparam_i_size,for all i) – 这是所有param_sizes的乘积
array_diff_key O(Σparam_i_size,for i!= 1) – 这是因为我们不需要遍历第一个数组。
array_merge O(Σarray_i,i!= 1) – 不需要迭代第一个数组
(union)O(n),其中n是第二个数组的大小(即array_first array_second) – 比array_merge少开销,因为它不必重新编号
array_replace O(Σarray_i,for all i)
随机:
shuffle O(n)
array_rand O(n) – 需要线性轮询。
显着大O:
array_fill O(n)
array_fill_keys O(n)
范围O(n)
array_splice O(offset length)
array_slice O(偏移长度)或O(n)如果length = NULL
array_keys O(n)
array_values O(n)
array_reverse O(n)
array_pad O(pad_size)
array_flip O(n)
array_sum O(n)
array_product O(n)
array_reduce O(n)
array_filter O(n)
array_map O(n)
array_chunk O(n)
array_combine O(n)
我要感谢Eureqa让它很容易找到Big-O的功能。这是一个惊人的免费程序,可以找到最适合任意数据的拟合函数。
编辑:
对于怀疑PHP数组查找是O(N)的那些人,我写了一个基准测试它(它们仍然有效O(1)为最真实的值)。
$tests = 1000000;
$max = 5000001;
for( $i = 1; $i <= $max; $i += 10000 ) {
//create lookup array
$array = array_fill( 0, $i, NULL );
//build test indexes
$test_indexes = array();
for( $j = 0; $j < $tests; $j++ ) {
$test_indexes[] = rand( 0, $i-1 );
}
//benchmark array lookups
$start = microtime( TRUE );
foreach( $test_indexes as $test_index ) {
$value = $array[ $test_index ];
unset( $value );
}
$stop = microtime( TRUE );
unset( $array, $test_indexes, $test_index );
printf( "%d,%1.15f\n", $i, $stop - $start ); //time per 1mil lookups
unset( $stop, $start );
}