順序執行耗時
= 所有任務執行耗時的總和: 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