Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TCP vs. UDP socket latency benchmark

I have implemented a small benchmark for socket communication via TCP and UDP in Python. Surprisingly, TCP is almost exactly double as fast as UDP.

To avoid routing effects, server and client are running on the same Unix machine, but on different threads.

Maybe the code is useful. Here is the server code:

import socket
import sys

host = 'localhost'  
port = 8888
buffersize = 8
server_address = (host, port) 

def start_UDP_server():
    socket_UDP = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    socket_UDP.bind(server_address)

    print("UDP server is running...")

    while True:
        data, from_address = socket_UDP.recvfrom(buffersize)
        if not data: break
        socket_UDP.sendto(data, from_address)
    socket_UDP.close()


def start_TCP_server():
    socket_TCP = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    socket_TCP.bind(server_address)
    socket_TCP.listen(1)

    print("TCP server is running...")

    while True:    
        client, client_address = socket_TCP.accept()

        while True:
            data = client.recv(buffersize)
            if not data: break
            client.sendall(data)

        client.close()

So you can run either start_TCP_server() or start_UDP_server().

On client side the code is:

import socket
import sys
import time

host = 'localhost'  
port = 8888
buffersize = 8
server_address = (host, port) 
client_address = (host, port+1)
N = 1000000


def benchmark_UDP():
    socket_UDP = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 
    socket_UDP.bind(client_address)

    print("Benchmark UDP...")

    duration = 0.0
    for i in range(0, N):
        b = bytes("a"*buffersize, "utf-8")
        start = time.time()
        socket_UDP.sendto(b, server_address)
        data, from_address = socket_UDP.recvfrom(buffersize)
        duration += time.time() - start

        if data != b:
            print("Error: Sent and received data are bot the same")

    print(duration*pow(10, 6)/N, "µs for UDP") 


def benchmark_TCP():
    socket_TCP = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    socket_TCP.connect(server_address)

    print("Benchmark TCP...")

    duration = 0.0
    for i in range(0, N):
        b = bytes("a"*buffersize, "utf-8")
        start = time.time()
        socket_TCP.sendall(b)
        data = socket_TCP.recv(buffersize)
        duration += time.time() - start

        if data != b:
            print("Error: Sent and received data are bot the same")

    print(duration*pow(10, 6)/N, "µs for TCP")
    socket_TCP.close()

Like for the server you can start the benchmark by benchmark_TCP() or benchmark_UDP().

The results are about 25 µs for TCP, and about 54 µs for UDP on Unix and even worse for Windows (about 30 µs for TCP and more than 200 µs for UDP). Why? I would expect a minimal advantage for UDP.

like image 300
Michael Dorner Avatar asked Sep 18 '15 14:09

Michael Dorner


People also ask

Is UDP lower latency than TCP?

Latency over UDP connections is much lower than over TCP connections. Any latency over UDP is primarily due to the network itself. TCP's various functions add additional latency to the data transmission.

How much faster is UDP compared to TCP?

Latency of isolated packets For isolated packets, these experiments showed median one-way latencies of about 16us over TCP and 12us over UDP.

Is UDP low latency?

UDP (User Datagram Protocol) is a communications protocol that is primarily used for establishing low-latency and loss-tolerating connections between applications on the internet. It speeds up transmissions by enabling the transfer of data before an agreement is provided by the receiving party.

Is UDP latency sensitive?

As mentioned above, TCP is a reliable connection oriented protocol and UDP is not. UDP is connectionless with no reliability built-in and unlike TCP there is no transmission window that can close. Therefore, UDP is completely unaffected by latency (there is no ACK process) as there is no re-transmission.


1 Answers

Your TCP socket is connected but your UDP socket is not. This means extra processing for every send/receive on the UDP socket. Call connect on each side for the UDP socket, just like you call connect/accept on the TCP socket.

Programs like iperf do this to measure accurately.

like image 125
David Schwartz Avatar answered Sep 28 '22 22:09

David Schwartz