microtime + usleep = incohérence totale (exemple)

nunja
Invité n'ayant pas de compte PHPfrance

20 avr. 2011, 18:19

Bonjour à tous.
Ce post pour demander de l'aide à propos d'un comportement étrange qui peut être reproduit tout le temps (apcahe2 + php5).
Je ne sait pas si je me plante mais je vais essayer d'expliquer la finalité de la démarche:

J'ai besoin d'envoyer des chunks de donnée binaires (par exemple 30), puis de calculer la bande passante moyenne sur ces 30 shunts en Kbit/s.
J'additionne chaque temps d'output dans une var, ainsi que la taille de chaque chunk, puis je fait le total à la fin.
	<?php
	
	// build my binary chunk
	$var= '';
	$o=9000;
	while($o--)
	{
		$var.= "testtest";
	}
	
	// get the size, prepare the memory.
	$size = strlen($var);
	$tt_sent = 0;
	$tt_time = 0;
	
	// I send my chunk 30 times
	for ($i = 0; $i < 30; $i++)
	{
		// start time
		$t = microtime(true);
		echo $var."\n";
		ob_flush();
		flush();
		$e = microtime(true);
		// end time
		// the difference should reprenent what it takes to the server to 
		// transmit chunk to client right ?
		
		// add this chuck bench to the total
		$tt_time += round($e-$t,4);
		$tt_sent += $size;
	}
	
	// total result
	echo "\n total: ".(($tt_sent*8)/($tt_time)/1024)."\n";
	
	?>
Dans l'exemple du dessus, ça semble marcher, mes résultats sont cohérents lorsque je limite ma bande passante sur le port 80.

Maintenant, supposons que j'ai besoin de limiter l'envoi de ces chunks ( car le client à assez de data à traiter avec un shunts sur une seconde ).

J'utilise usleep(1000000), ainsi, après l'envoit d'un chunk puis l'estimation du temps que cela à pris, je fait une petite pause.
	<?php
	
	// build my binary chunk
	$var= '';
	$o=9000;
	while($o--)
	{
		$var.= "testtest";
	}
	
	// get the size, prepare the memory.
	$size = strlen($var);
	$tt_sent = 0;
	$tt_time = 0;
	
	// I send my chunk 30 times
	for ($i = 0; $i < 30; $i++)
	{
		// start time
		$t = microtime(true);
		echo $var."\n";
		ob_flush();
		flush();
		$e = microtime(true);
		// end time
		// the difference should reprenent what it takes to the server to 
		// transmit chunk to client right ?
		
		// add this chuck bench to the total
		$tt_time += round($e-$t,4);
		$tt_sent += $size;
	
		usleep(1000000);
	}
	
	// total result
	echo "\n total: ".(($tt_sent*8)/($tt_time)/1024)."\n";
	
	?>

Dans l'exemple ci-dessus, mon calcul final est tout bonnement incohérent, j'ai des saut de 70000Kbit/s, à + d'un millions, car l'estimation du temps d'output est complètement falsifiée : (le temps calculé (microtime(true)) d'envoi de chaque chunk devient ridiculement court, même avec des données binaires plus importantes).

J'ai besoin d'aide pour comprendre ce qu'il va pas dans cet exemple, ou si c'est un comportement normal (ob_flush();/flush(); asynchrones …)

Config: LAMP php 5.3


Merci !

Eléphant du PHP | 92 Messages

21 avr. 2011, 09:55

Hello,

je comprends peut être pas ce que tu fais mais, si tu utilise ob_flush(), tu devrais pas mettre ob_start() avant pour qu'il commence la mise en buffer ?
Programmer c'est 20% de syntaxe pour 80% de réflexion et dans les 20% de syntaxe il faut encore compter une bonne dose de réflexion...
Je vous donne des conseils, pas des solutions toutes faites...

nunja
Invité n'ayant pas de compte PHPfrance

21 avr. 2011, 15:27

J'ai essayé aussi, j'obtient le même résultat.

Eléphant du PHP | 92 Messages

21 avr. 2011, 17:11

En tout cas une chose est sûre.
Un caractère de ta chaine ne vaut pas un bit (ce que tu sembles sous-entendre quand tu fais $tt_sent*8), à la rigueur un octet et encore en fonction de l'encoding utilisé c'est pas forcément vrai...
Donc ce que tu peux mesurer c'est le nombre de chunk par secondes à la rigueur...
Programmer c'est 20% de syntaxe pour 80% de réflexion et dans les 20% de syntaxe il faut encore compter une bonne dose de réflexion...
Je vous donne des conseils, pas des solutions toutes faites...

nunja
Invité n'ayant pas de compte PHPfrance

21 avr. 2011, 17:55

Si on remplace "testtest" par un pack('N', 123456); on obtiens 4 bytes.
pour l'avoir en bits on *8.

Mais c'est pareil. L'impression que le usleep agit sur le microtime ...