<?php 
set_time_limit(300);
error_reporting(E_ALL);
 
class test {
	function func() {}
}
$test = new test;
 
$nIter = 1000000;
$argNums = [0, 1, 2, 3, 4, 5, 6, 7, 8, 20];
foreach ($argNums as $argNum) {
	$args = $argNum == 0 ? [] : array_fill(0, $argNum, null);
	 
	$startTime = microtime(true);
	for ($i = 0; $i < $nIter; ++$i) {
		call_user_func_array(array($test, "func"), $args);
	}
	
	$endTime = microtime(true);
	echo "cufa..... with $argNum args took ", $endTime - $startTime, "<br/>";
	
	$startTime = microtime(true);
	
	for ($i = 0; $i < $nIter; ++$i) {
		switch (count($args)) {
			case 0: $test->func(); break;
			case 1: $test->func($args[0]); break;
			case 2: $test->func($args[0], $args[1]); break;
			case 3: $test->func($args[0], $args[1], $args[2]); break;
			case 4: $test->func($args[0], $args[1], $args[2], $args[3]); break;
			default: call_user_func_array(array($test, "func"), $args); break;
		}
	}
	$endTime = microtime(true);
	echo "direct4 with $argNum args took ", $endTime - $startTime, "<br/>";
	$startTime = microtime(true);
	
	for ($i = 0; $i < $nIter; ++$i) {
		switch (count($args)) {
			case 0: $test->func(); break;
			case 1: $test->func($args[0]); break;
			case 2: $test->func($args[0], $args[1]); break;
			case 3: $test->func($args[0], $args[1], $args[2]); break;
			case 4: $test->func($args[0], $args[1], $args[2], $args[3]); break;
			case 5: $test->func($args[0], $args[1], $args[2], $args[3], $args[4]); break;
			default: call_user_func_array(array($test, "func"), $args); break;
		}
	}
	$endTime = microtime(true);
	echo "direct5 with $argNum args took ", $endTime - $startTime, "<br/>";
	$startTime = microtime(true);
	
	for ($i = 0; $i < $nIter; ++$i) {
		switch (count($args)) {
			case 0: $test->func(); break;
			case 1: $test->func($args[0]); break;
			case 2: $test->func($args[0], $args[1]); break;
			case 3: $test->func($args[0], $args[1], $args[2]); break;
			case 4: $test->func($args[0], $args[1], $args[2], $args[3]); break;
			case 5: $test->func($args[0], $args[1], $args[2], $args[3], $args[4]); break;
			case 6: $test->func($args[0], $args[1], $args[2], $args[3], $args[4], $args[5]); break;
			default: call_user_func_array(array($test, "func"), $args); break;
		}
	}
	$endTime = microtime(true);
	echo "direct6 with $argNum args took ", $endTime - $startTime, "<br/>";
	$startTime = microtime(true);
	
	for ($i = 0; $i < $nIter; ++$i) {
		switch (count($args)) {
			case 0: $test->func(); break;
			case 1: $test->func($args[0]); break;
			case 2: $test->func($args[0], $args[1]); break;
			case 3: $test->func($args[0], $args[1], $args[2]); break;
			case 4: $test->func($args[0], $args[1], $args[2], $args[3]); break;
			case 5: $test->func($args[0], $args[1], $args[2], $args[3], $args[4]); break;
			case 6: $test->func($args[0], $args[1], $args[2], $args[3], $args[4], $args[5]); break;
			case 7: $test->func($args[0], $args[1], $args[2], $args[3], $args[4], $args[5], $args[6]); break;
			default: call_user_func_array(array($test, "func"), $args); break;
		}
	}
	$endTime = microtime(true);
	echo "direct7 with $argNum args took ", $endTime - $startTime, "<br/>";
	$startTime = microtime(true);
	
	for ($i = 0; $i < $nIter; ++$i) {
		switch (count($args)) {
			case 0: $test->func(); break;
			case 1: $test->func($args[0]); break;
			case 2: $test->func($args[0], $args[1]); break;
			case 3: $test->func($args[0], $args[1], $args[2]); break;
			case 4: $test->func($args[0], $args[1], $args[2], $args[3]); break;
			case 5: $test->func($args[0], $args[1], $args[2], $args[3], $args[4]); break;
			case 6: $test->func($args[0], $args[1], $args[2], $args[3], $args[4], $args[5]); break;
			case 7: $test->func($args[0], $args[1], $args[2], $args[3], $args[4], $args[5], $args[6]); break;
			case 8: $test->func($args[0], $args[1], $args[2], $args[3], $args[4], $args[5], $args[6], $args[7]); break;
			default: call_user_func_array(array($test, "func"), $args); break;
		}
	}
	$endTime = microtime(true);
	echo "direct8 with $argNum args took ", $endTime - $startTime, "<br/>";
	echo "<br/>";
}