上一篇关于Python和Go的文章是:

什么?Python Celery 也能调度Go worker?

文中我们讨论了Python Celery调度Go写的worker的方法。

而在 优劣互补! Python+Go结合开发的探讨

一文中,我们讨论了Go在单线程计算性能上的优势。

现在,考虑这样的一种场景:

我们需要从某些网址中同步数据并进行计算,保存到本地redis缓存中。

现在,我们可以通过编写Go Worker的方式,将计算和保存的过程保存在本地的redis缓存中,然后使用Celery来调度这些任务。

问题在于,从这些网址中获取数据的步骤,写在Go Worker里是否合适?Go进行网络请求是否比Python更稳定、速度更快?今天我们就来比较一下。

1.同步比较

首先,试试Go语言请求百度,获得这个请求和拿到回应之间的时间差:

package main

import (
    "fmt"
	"time"
	"net/http"
)

func main() {

	t1 := time.Now()
    resp, err := http.Get("https://baidu.com")
	t2 := time.Now()
	
	fmt.Println("spend time:", t2.Sub(t1))
	
    if err != nil {
		fmt.Println("请求失败")
    }

    defer resp.Body.Close()
}

结果如下:

可以看到,平均耗时在250ms左右。

然后测试Python的requests模块请求网站:

import requests
import time
t1 = time.time()*1000
requests.get("https://baidu.com")
t2 = time.time()*1000
print(t2-t1)

平均约220ms,似乎在单个请求的情况下,Python略胜一筹。

但是单个请求的比较是没有意义的,因为这个差异可以忽略不计。

重点还是在下面并发请求的比较上。

2.并发比较

现在,我们试试用Go语言并发请求10次百度:

package main

import (
    "fmt"
	"time"
	"net/http"
    "sync"
)

func test_get() {
	http.Get("https://baidu.com")
}

func main() {
	var numbers = 10
    var wg sync.WaitGroup
    wg.Add(numbers)
	t1 := time.Now()
	for i := 0; i < numbers; i++ {
		go func() {
			test_get()
			wg.Done()
		}()
	}
	wg.Wait()
	t2 := time.Now()
	
	fmt.Println("spend time:", t2.Sub(t1))
}

效果如下:

平均消耗在300ms左右,和单次请求差不多,速度还是相当快的。

接下来试试Python的并发请求,值得注意的是,这里没有用requests模板,因为requests模块是同步的,这一点一定要注意。

因此在这里需要使用aiohttp进行并发请求:

import asyncio
import time
from aiohttp import ClientSession


async def request_web():
    async with ClientSession() as session:
        async with session.get("https://baidu.com"):
            pass
 
loop = asyncio.get_event_loop()
tasks=[]
for i in range(10):
    tasks.append(request_web())

t1 = time.time()*1000
loop.run_until_complete(asyncio.wait(tasks))
t2 = time.time()*1000
print(t2 - t1)

测试结果如下:

可以看到,平均耗时在500ms左右,在并发的时候,其速度相比于Go略逊一筹。

3.总结

可以看到,Python在单个请求的时候(使用requests模块)速度比Go稍微快一丢丢,但是这样的区别几乎可以忽略不计。

在并发10次请求的情况下,Go平均耗时300ms,而Python平均耗时500ms,Go略胜一筹。

我们的文章到此就结束啦,如果你喜欢今天的Python 实战教程,请持续关注Python实用宝典。

有任何问题,可以在公众号后台回复:加群,回答相应的红字验证信息,进入互助群询问,请一定记得回复红字的问题,这样我才会拉你进群。

原创不易,希望你能在下面点个赞和在看支持我继续创作,谢谢!


​Python实用宝典 (pythondict.com)
不只是一个宝典
欢迎关注公众号:Python实用宝典

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。