Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The speed of socket is 120MB/s on a computer, is it normal?

I tested the performance of transferring data from a program to another over socket on a single computer, and the speed is 120MBytes/s, is it normal?

My server and client programs are both extremely simple.

And my computer is AMD Athlon X2 4000+, 4G DDR2 667 ram, with windows xp sp3.

My friend said it was slow, and should be faster. But I don't know how can I improve them, or is there any other libraries I can try to get a better speed?

UPDATE

The server and client programs were both on my own computer, a single computer. The network card will limit the speed or not?


Server.java

import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class SimpleServer {
    public static void main(String[] args) throws Exception {
        ServerSocket server = new ServerSocket(6666);
        Socket socket = server.accept();
        OutputStream output = socket.getOutputStream();

        byte[] bytes = new byte[10 * 1024]; // 10K
        for (int i = 0; i < bytes.length; i++) { bytes[i] = 12; } // fill the bytes

        // send them again and again
        while (true) {
            output.write(bytes);
        }
    }
}

Client.java

public class SimpleClient {

    public static void main(String[] args) throws Exception {
        Socket socket = new Socket("127.0.0.1", 6666);
        InputStream input = socket.getInputStream();
        long total = 0;
        long start = System.currentTimeMillis();

        byte[] bytes = new byte[10240]; // 10K

        // read the data again and again
        while (true) {
            int read = input.read(bytes);
            total += read;
            long cost = System.currentTimeMillis() - start;
            if (cost > 0 && System.currentTimeMillis() % 1000 == 0) {
                 System.out.println("Read " + total + " bytes, speed: " + (total / (1024.0*1024)) / (cost / 1000.0) + " MB/s");
            }
        }
    }

}
like image 795
Freewind Avatar asked Oct 26 '11 13:10

Freewind


3 Answers

Can you give me the output of this program?

public class SimpleServer {
    public static void main(String[] args) throws Exception {
        ServerSocket server = new ServerSocket(6666);
        Socket socket = server.accept();
        OutputStream output = socket.getOutputStream();

        byte[] bytes = new byte[32*1024]; // 32K
        while (true) {
            output.write(bytes);
        }
    }
}
public class SimpleClient {
    public static void main(String[] args) throws Exception {
        Socket socket = new Socket("127.0.0.1", 6666);
        InputStream input = socket.getInputStream();
        long total = 0;
        long start = System.currentTimeMillis();

        byte[] bytes = new byte[32*1024]; // 32K
        for(int i=1;;i++) {
            int read = input.read(bytes);
            if (read < 0) break;
            total += read;
            if (i % 500000 == 0) {
                long cost = System.currentTimeMillis() - start;
                System.out.printf("Read %,d bytes, speed: %,d MB/s%n", total, total/cost/1000);
            }
        }
    }
}

on my machine prints

Read 25,586,204,672 bytes, speed: 5,245 MB/s
Read 53,219,426,304 bytes, speed: 5,317 MB/s
Read 85,018,968,064 bytes, speed: 5,416 MB/s
Read 117,786,968,064 bytes, speed: 5,476 MB/s

Try sending 32K blocks many times (for at least 2 seconds) and you should get 400 MB/s or more. e.g. at least 10,000 times.

On a very fast machine you can get 1 GB/s on a single client. With multiple clients you might get 8 GB/s.

Here is an example

Making file transfer more efficient Java


If you have a 100 Mb card you can expect around 11 MB/s (bytes per second).

Similarly for 1 Gb ethernet youc an expect around 110 MB/s

For a 10 Gig-E ethernet you might get up to 1 GB/s however you might only get half this unles syour system is highly tuned.

like image 187
Peter Lawrey Avatar answered Oct 25 '22 00:10

Peter Lawrey


You're only transferring 10k bytes to perform your test. There is overhead to a lot of what you're doing and such a small set of data may be getting skewed by this overhead. (e.g. creating sockets, allocating memory etc.) You should create and transfer a much larger set of data (dozens of MBs+) to get a more realistic idea of what's going on. Doing this will make the overhead a smaller, less significant part of the data transfer process.

You should also perform this test a number of times (> 10) and take the average because your computer will be under loads from services, network transfers etc. at different, random points in time and these loads will affect your transfer rate. With 10+ iterations you could also drop any run times that are unusually slow, such as > 2 standard deviations.

like image 43
Paul Sasik Avatar answered Oct 25 '22 02:10

Paul Sasik


The network card will limit the speed or not?

You are using 127.0.0.1 - the local / loopback address. Traffic from / to that address doesn't pass through the network card.

This means that this is not a valid way to measure real network throughput. However, it is a reasonable measure of Java's ability to move data through the local network stack ... on your machine.


What would be interesting would be to compare the result you are getting with an equivalent client / server pair written in C or C++.

like image 34
Stephen C Avatar answered Oct 25 '22 01:10

Stephen C