[英]Bad UDP performance in Golang vs. Python
我想尽可能快地发送尽可能多的 UDP 数据包。 我尝试了在net包中发送 UDP 数据的不同方法,但最终得到了以下结果;
func main() {
for i := 0; i < THREADS; i++ {
go loopSendHello()
}
// Sleep forever
<-make(chan bool, 1)
}
func loopSendHello() {
for {
sendHello()
}
}
func sendHello() {
// Setup conn
addr := net.UDPAddr{
IP: net.IP{192, 168, 1, xxx},
Port: 1337,
}
conn, err := net.ListenPacket("udp", "")
if err != nil {
log.Fatal("Listen:", err)
}
n, err := conn.WriteTo([]byte("hello"), &addr)
if err != nil {
log.Fatal("Error while writing to conn! :", err)
}
conn.Close()
}
THREADS 由 runtime.NumCPU() btw 定义。 使用 Wireshark 对此进行基准测试可得出以下结果: 大约 90 毫秒的延迟(如果我没看错的话)。
虽然这是 Python 中的情况(此函数在 4 个线程中运行):
def sendHello():
while True:
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
addr = ("192.168.1.xxx", 1337)
s.sendto(data, addr)
except:
print("error")
使用 Wireshark 进行基准测试: . 这是从 1ms 到大约 10ms 的延迟! 疯狂的差异。
如何在 Go 中匹配 python 的速度?
所以我决定非常快速地创建一个简单的基准测试,发送 200 000 个 UDP 数据包,没有任何线程或糟糕的编程技术。 基准测试介于 Go 和 Python 之间。 此外,我希望尽可能快地考虑基准测试。 我考虑过使用 C,但由于我在 Windows 上,使用 Rust 似乎最容易。
防锈代码:
use std::time::{SystemTime};
use std::net::UdpSocket;
const DATA: &[u8] = &[0; 1024];
fn main() {
let time_start = SystemTime::now();
let socket = UdpSocket::bind("192.168.1.155:1339").unwrap();
for _ in 0..200000 {
socket.send_to(DATA, "192.168.1.122:80").unwrap();
}
let elapsed = time_start.elapsed().unwrap();
println!("Time {} ms to send 200 000 packets", elapsed.as_millis());
}
平均结果(内置 --release 模式): Time 1863 ms to send 200 000 packets
对于 Go 基准测试,这基本上是代码:
var buff = []byte("")
func main() {
buff = []byte(RandomString(1024))
conn, err := net.ListenUDP("udp", &net.UDPAddr{})
if err != nil {
log.Fatal("Listen:", err)
}
loopSendHello(*conn)
conn.Close()
}
func loopSendHello(conn net.UDPConn) {
timeStart := time.Now()
for i:=0; i < 200000; i++ {
sendHelloEdited(&conn)
}
timeStop := time.Now()
timeDelta := timeStop.Sub(timeStart)
fmt.Println("Took", timeDelta.Milliseconds(), "ms to send 200 000 packets.")
}
// targetAddr is target address in form of net.UDPAddr
func sendHelloEdited(conn *net.UDPConn) {
_, err := conn.WriteToUDP(buff, &targetAddr)
if err != nil {
log.Fatal("Error while writing to conn! :", err)
}
}
去平均。 结果: Took 1959 MS to send 200 000 packets.
现在对于 Python 测试,这是代码:
def main():
x = 0
data = random._urandom(1024)
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
addr = (str(ip), int(port))
startTime = datetime.datetime.now()
while x < 200000:
s.sendto(data, addr)
x += 1
s.close()
endTime = datetime.datetime.now()
deltaTime = endTime - startTime
print("Took", deltaTime, "to send 200 000 packets")
main()
有趣的是,python 结果总是很快,平均。 输出: Took 0:00:01.831531 to send 200 000 packets
所以看起来 Go 确实是最慢的,但只是微不足道。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.