On 07/02/13 06:36, Jeroen De Dauw wrote: > Those benchmarks are only testing some rather small arrays no? > > I did some stuff a while back as well: > https://github.com/JeroenDeDauw/php/blob/master/profile/array-empty.php
That is an interesting way to do benchmarks. XHProf has a bug in it which caused the times it reported to be off by a factor of 100 or so for about half the runs. I fixed it, and also unrolled the size loop to allow the xhprof_enable() call to be done only once, reducing the effects of inaccurate RDTSC calibration. I increased the iteration count and switched to a normal loop counter instead of range() to avoid thrashing the L2 cache. The XHProf overhead was distorting the count() case, since it adds a profiling hook to internal function calls. Specifying the XHPROF_FLAGS_NO_BUILTINS flag to xhprof_enable() reduced the time for counting small arrays by a factor of 2. I added the "!" operator to the list of things to benchmark. The results were: * ! and empty() within an error bar of each other, ~700ns per iteration * Triple-equals took 1300ns per iteration * count() took around 3us plus 370ns per array element (determined by linear regression). The modified script: http://paste.tstarling.com/p/JYnLPi.html The XHProf patch: http://paste.tstarling.com/p/tgCAyC.html The reason count() is O(N) in this case is because $array is a reference. See zend_send_by_var_helper in zend_vm_def.h: } else if (PZVAL_IS_REF(varptr)) { zval *original_var = varptr; ALLOC_ZVAL(varptr); ZVAL_COPY_VALUE(varptr, original_var); Z_UNSET_ISREF_P(varptr); Z_SET_REFCOUNT_P(varptr, 0); zval_copy_ctor(varptr); If you pass the array as a non-reference parameter, you get O(1) performance of count(): function a( $array ) { for ( $i = 0; $i < 10000000; $i++ ) { $a = count( $array ) == 0; } } It takes around 2us per iteration that way, regardless of array size. -- Tim Starling _______________________________________________ Wikitech-l mailing list [email protected] https://lists.wikimedia.org/mailman/listinfo/wikitech-l
