服务器端程序( python、go 分别去请求他)
package main
import (
"log"
"math/rand"
"net/http"
"time"
)
func hello(w http.ResponseWriter, r *http.Request) {
time.Sleep(time.Second * time.Duration(rand.Intn(5)))
w.Write([]byte("hello world"))
}
func main() {
http.HandleFunc("/", hello)
if err := http.ListenAndServe(":8080", nil); err != nil {
log.Fatal(err)
}
}
下面是比较的程序:
python 版本:
time python main.py
输出是 python main.py 0.37s user 0.13s system 3% cpu 16.545 total
import concurrent.futures
import requests
def do_run(task_name):
resp = requests.get("http://localhost:8080")
return f"{task_name}-{resp.content}"
if __name__ == "__main__":
with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
futures = [executor.submit(do_run, f"task-{i}") for i in range(40)]
for future in concurrent.futures.as_completed(futures):
print(future.result())
print("Done!")
go 版本:
time go run main.go
输出是: go run main.go 0.63s user 0.33s system 19% cpu 4.927 total
package main
import (
"fmt"
"io/ioutil"
"log"
"net/http"
"sync"
)
var httpClient http.Client
func init() {
httpClient = *http.DefaultClient
}
func doRun(taskName string, taskChan chan string, wg *sync.WaitGroup) {
resp, err := httpClient.Get("http://localhost:8080")
if err != nil {
taskChan <- "error"
log.Fatal(err)
}
b, err := ioutil.ReadAll(resp.Body)
if err != nil {
taskChan <- "error"
log.Fatalln(err)
}
taskChan <- fmt.Sprintf("%s--%s", taskName, string(b))
wg.Done()
}
func main() {
taskChan := make(chan string)
wg := sync.WaitGroup{}
go func() {
wg.Add(40)
wg.Wait()
close(taskChan)
}()
for i := 0; i < 40; i++ {
go doRun(fmt.Sprintf("task-%d", i), taskChan, &wg)
}
for r := range taskChan {
fmt.Println(r)
}
fmt.Println("Done")
}
请教各位程序大佬看看我 python 程序错在哪里?
1
baojiweicn2 2019-03-23 16:03:31 +08:00 via Android
能不能用 aiohttp 加上 await 而不是线程试一下
|
2
676529483 2019-03-23 16:14:38 +08:00
python 你 socket 连接没有复用啊,应该先 session=request.Session()创建会话,再用 session.get()去请求
再说 go 用的协程哎,python 改下 aiohttp+async 试下 |
3
ipwx 2019-03-23 16:28:28 +08:00
Python 没有高效的多线程,因为 GIL。。。
|
4
hujianxin OP aio 确实可以在这个 case 中达到 go 的效率,但是 python 世界中大多数操作都是不支持 async 的,比如我想使用 s3 的 python sdk 来操作 s3,这个就办不了了。。。
|
5
hujianxin OP 原因是我 python 只用了 5 个线程,我错了,此贴终结
|