IOUtils.toString занимает много времени

У меня есть этот класс, который открывает HTTP-сервер и прослушивает порт. Ответ представляет собой http-заголовок плюс объект json. Класс берет входной поток с сервера, преобразует его в строку, фильтрует заголовок http и анализирует объект json.

Дело в том, что преобразование входного потока в строку занимает около 3 секунд. Есть ли способ быстрее прочитать входной поток?

public class GamestateListener {

private static int PORT = 3001; // Port specified in your cfg
public static ServerSocket listenServer;
private static JSONObject MYJSONOBJ;

public GamestateListener() {
    try {
        listenServer = new ServerSocket(PORT); // open new Server Socket
        System.out.println("Started Socket..."); // printing out started
                                                    // listening
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}

public JSONObject listenAndParseJSON() throws IOException {

    System.out
            .println("Listening for connection on port " + PORT + " ...."); // printing
                                                                            // out
                                                                            // started
                                                                            // listening

    try (Socket socket = listenServer.accept()) { // wait for connection

        System.out.println("Start get From Socket           "
                + System.currentTimeMillis());
        InputStream mis = socket.getInputStream();
        System.out.println("Stop get From Socket           "
                + System.currentTimeMillis());
        String responseString = IOUtils.toString(mis, "UTF-8");
        System.out.println("Stop to String           "
                + System.currentTimeMillis());
        MYJSONOBJ = new JSONObject(responseString.substring(responseString
                .indexOf("{")));// split the response string

        return MYJSONOBJ;// return the json obj

    } catch (Exception e) {
        MYJSONOBJ = new JSONObject("{ERROR:True}");// create error obj
        return MYJSONOBJ;// return it
    }

}

}

person Trojan    schedule 09.02.2016    source источник
comment
насколько велик объект json?   -  person Woot4Moo    schedule 09.02.2016
comment
Вы проверяли, насколько быстро данные отправляются на сервер?   -  person Gerald Mücke    schedule 09.02.2016
comment
Я думаю, что ваш impl не измеряет преобразование toString. Он измеряет время, необходимое для ПРОЧТЕНИЯ входного потока и его преобразования. Так что я думаю, что 3 секунды связаны с вашей сетью   -  person pandaadb    schedule 09.02.2016


Ответы (1)


Вы не измеряете то, что вы думаете о себе. Здесь:

System.out.println("Start get From Socket           "
        + System.currentTimeMillis());
InputStream mis = socket.getInputStream();
System.out.println("Stop get From Socket           "
        + System.currentTimeMillis());

... вы, кажется, думаете, что прочитали все данные, когда getInputStream() возвращается. У вас нет. Вы только что получили поток, из которого можно читать. Это значит, что есть связь, но не более того.

Если вы хотите измерить, сколько времени занимает просто чтение всех данных (а не их фактическая обработка), вы можете сделать что-то вроде:

System.out.println("Start get From Socket           "
        + System.currentTimeMillis());
InputStream mis = socket.getInputStream();
byte[] buffer = new byte[8192];
// Read all the data (but ignore it)
while ((mis.read(buffer)) != -1) ;
System.out.println("Stop get From Socket           "
        + System.currentTimeMillis());

Конечно, тогда не будет никаких данных для считывания остального кода, но вы увидите, сколько времени занимает только чтение данных. Я предполагаю, что это будет около 3 секунд... что может быть связано с медленной сетью или с тем, что клиенту требуется много времени, чтобы даже отправить все данные. (Он может подключиться, заснуть на 2,9 секунды и затем отправить кучу данных.)

person Jon Skeet    schedule 09.02.2016
comment
Хорошо. Спасибо. Клиент представляет собой интеграцию csgo gamestate. Уже есть несколько скриптов Python, которые используют его, и они, кажется, могут реагировать на происходящие события намного быстрее. developer.valvesoftware.com/wiki/ - person Trojan; 09.02.2016
comment
@Trojan: Ну, мы не можем точно сказать, но первое, что вы должны сделать, это попробовать использовать диагностическое изменение, которое я предоставил выше. Тогда вы сможете сказать, какие IOUtils.toString накладные расходы превышают время, необходимое для простого чтения данных. - person Jon Skeet; 09.02.2016
comment
Вывод: Start get From Socket 1455040519365 Stop get From Socket 1455040524356 Таким образом, он похож на старый. - person Trojan; 09.02.2016
comment
@Trojan: Верно, это около 5 секунд. Так что, судя по всему, это не IOUtils.toString. Вам нужно посмотреть, почему клиент так долго публикует данные (и сколько данных он публикует). - person Jon Skeet; 09.02.2016