队列(Queue)

异步并发的服务器里经常使用队列实现生产者消费者模型,解决并发排队问题。PHP的SPL标准库中提供了SplQueue扩展内置的队列数据结构。另外PHP的数组也提供了array_poparray_shift可以使用数组模拟队列数据结构。

SplQueue

  1. $queue = new SplQueue;
  2. //入队
  3. $queue->push($data);
  4. //出队
  5. $data = $queue->shift();
  6. //查询队列中的排队数量
  7. $n = count($queue);

Array模拟队列

  1. $queue = array();
  2. //入队
  3. $queue[] = $data;
  4. //出队
  5. $data = array_shift($queue);
  6. //查询队列中的排队数量
  7. $n = count($queue);

性能对比

虽然使用Array可以实现队列,但实际上性能会非常差。在一个大并发的服务器程序上,建议使用SplQueue作为队列数据结构。

100万条数据随机入队、出队,使用SplQueue仅用2312.345ms即可完成,而使用Array模拟的队列的程序根本无法完成测试,CPU一直持续在100%。

降低数据条数到1万条后(100倍),也需要260ms才能完成测试。

SplQueue

  1. $splq = new SplQueue;
  2. for($i = 0; $i < 1000000; $i++)
  3. {
  4. $data = "hello $i\n";
  5. $splq->push($data);
  6. if ($i % 100 == 99 and count($splq) > 100)
  7. {
  8. $popN = rand(10, 99);
  9. for ($j = 0; $j < $popN; $j++)
  10. {
  11. $splq->shift();
  12. }
  13. }
  14. }
  15. $popN = count($splq);
  16. for ($j = 0; $j < $popN; $j++)
  17. {
  18. $splq->pop();
  19. }

Array队列

  1. $arrq = array();
  2. for($i = 0; $i <1000000; $i++)
  3. {
  4. $data = "hello $i\n";
  5. $arrq[] = $data;
  6. if ($i % 100 == 99 and count($arrq) > 100)
  7. {
  8. $popN = rand(10, 99);
  9. for ($j = 0; $j < $popN; $j++)
  10. {
  11. array_shift($arrq);
  12. }
  13. }
  14. }
  15. $popN = count($arrq);
  16. for ($j = 0; $j < $popN; $j++)
  17. {
  18. array_shift($arrq);
  19. }