顺序执行耗时
= 所有任务执行耗时的总和: t1+t2+t3...
并发执行耗时
= 所有任务执行耗时的最大值: max(t1, t2, t3, ...)
按照 test1.php
正常执行代码, 若 for
里每个调用都需要耗时 2s
, 那执行5次下来就需要 10s
test2.php
和 test3.php
用 swoole
提供的并发调用功能, 利用 协程(go)
+ 通道(channel)
特性, 异步
并发执行, 所需时间为 2s
, 大大提高了效率
官方文档
WaitGroup: https://wiki.swoole.com/#/coroutine/wait_group
go + channel: https://wiki.swoole.com/#/coroutine/multi_call
代码:
# test1.php
$result = [];
for($i = 0; $i < 5; $i++) {
//模拟消耗时间
sleep(2);
$result[] = $i;
}
var_dump(json_encode($result));
# test2.php
// WaitGroup
Co\run(function () {
$wg = new \Swoole\Coroutine\WaitGroup();
$result = [];
for($i = 0; $i < 5; $i++) {
$wg->add();
go(function () use ($wg, &$result, $i) {
//模拟消耗时间
Co::sleep(2);
$result[] = $i;
$wg->done();
});
}
//挂起当前协程,等待所有任务完成后恢复
$wg->wait();
var_dump(json_encode($result));
});
# test3.php
// 协程(go) + 通道(channel)
Co\run(function () {
$n = 5;
$result = [];
$chan = new chan($n);
for($i = 0; $i < $n; $i++) {
go(function () use ($chan, $i) {
//模拟消耗时间
Co::sleep(2);
$chan->push($i);
});
}
for ($i = 0; $i < $n; $i++) {
$result[] = $chan->pop();
}
var_dump(json_encode($result));
});
耗时参考:
# time php test1.php
string(11) "[0,1,2,3,4]"
real 0m10.024s
user 0m0.004s
sys 0m0.016s
# time php test2.php
string(11) "[0,4,3,2,1]"
real 0m2.035s
user 0m0.013s
sys 0m0.017s
# time php test3.php
string(11) "[0,4,3,2,1]"
real 0m2.031s
user 0m0.019s
sys 0m0.008s