Скорость сокета на компьютере 120 МБ / с, это нормально? - PullRequest
11 голосов
/ 26 октября 2011

Я проверил производительность передачи данных из программы в другую через сокет на одном компьютере, и скорость составляет 120 МБ / с , это нормально?

Мои серверные и клиентские программы чрезвычайно просты.

А у меня компьютер AMD Athlon X2 4000+, 4G DDR2 667, с Windows XP SP3.

Мой друг сказал, что это медленно и должно быть быстрее. Но я не знаю, как я могу улучшить их, или есть ли другие библиотеки, которые я могу попытаться улучшить?

UPDATE

Сервер и клиентские программы были на моем собственном компьютере, один компьютер . сетевая карта будет ограничивать скорость или нет?


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");
            }
        }
    }

}

Ответы [ 6 ]

12 голосов
/ 26 октября 2011

Можете ли вы дать мне вывод этой программы?

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);
            }
        }
    }
}

на моей машине печатает

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

Попробуйте отправить 32K блоков много раз (не менее 2 секунд), и вы получите 400 МБ / с или более. например не менее 10000 раз.

На очень быстрой машине вы можете получить 1 ГБ / с на одном клиенте. С несколькими клиентами вы можете получить 8 ГБ / с.

Вот пример

Повышение эффективности передачи файлов Java


Если у вас есть карта на 100 МБ, вы можете ожидать около 11 МБ / с (байт в секунду).

Аналогично для Ethernet на 1 ГБ ожидается около 110 МБ / с

Для Ethernet 10 Гбит-E вы можете получить до 1 ГБ / с, но вы можете получить только половину этой системы Unles Syour с высокой настройкой.

10 голосов
/ 26 октября 2011

Для выполнения теста вы передаете только 10 Кбайт. Это связано с большим количеством работы, и такой небольшой набор данных может быть искажен этими издержками. (например, создание сокетов, выделение памяти и т. д.) Вам следует создавать и передавать гораздо больший набор данных (десятки МБ +), чтобы получить более реалистичное представление о том, что происходит. Это сделает накладные расходы меньшей, менее значимой частью процесса передачи данных.

Вы также должны выполнить этот тест несколько раз (> 10) и взять среднее значение, потому что ваш компьютер будет загружен службами, сетевыми передачами и т. Д. В разные случайные моменты времени, и эти нагрузки будут влиять на вашу скорость передачи. , С 10+ итерациями вы также можете отбросить любое время выполнения, которое является необычно медленным, например> 2 стандартных отклонения.

5 голосов
/ 26 октября 2011

Сетевая карта будет ограничивать скорость или нет?

Вы используете 127.0.0.1 - локальный / петлевой адрес.Трафик с / на этот адрес не проходит через сетевую карту.

Это означает, что это недопустимый способ измерения реальной пропускной способности сети.Однако это разумная мера способности Java перемещать данные через стек локальной сети ... на вашем компьютере.


Интересно было бы сравнить полученный результат с эквивалентнымпара клиент / сервер, написанная на C или C ++.

1 голос
/ 27 октября 2011

Тестирование полосы пропускания между двумя узлами на одном хосте вообще не задействует сетевой адаптер или сеть, все возвращается обратно. Поэтому ваши данные в основном бессмысленны. Попробуйте это между двумя компьютерами.

0 голосов
/ 14 июня 2017

Что ж, это интересно, но эта реализация nio была на одном уровне с SimpleServer / SimpleClient, представленным выше (и иногда даже побеждает его) (хотя это только в случае однопоточного режима, который в любом случае больше один к одному !!!)

И SimpleServer / SimpleClient, и nio IntegTestLocalhostThroughput.java, представленные в этом каталоге ...

https://github.com/deanhiller/webpieces/tree/master/core/core-asyncserver/src/test/java/org/webpieces/nio/api/throughput

Я просто подумал, что довольно интересно, что nioв основном так же быстро, но масштабируется лучше, чем старые вещи io.

0 голосов
/ 30 октября 2011

WinXP не поддерживает автоматическое масштабирование окна, и, вероятно, размер буфера отправки / получения сокета слишком мал для теста пропускной способности.

Более того, FileInputStream (сокет практически использует FileInputStream) имеет меньший char []буфер на винде чем линукс в родном коде.Чтение / запись осуществляется через вспомогательный буфер в стеке, и большой кусок, который вы помещаете, направляется через него.

Использование большого прямого буфера (такого же размера, как и буфера сокетов) - ваш лучший выбор для пропускной способности.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...