Reading inputStream using BufferedReader.readLine() is too slow

后端 未结 2 747
一整个雨季
一整个雨季 2020-12-13 09:14

I am using following code.

BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line = null;

StringBuilder responseD         


        
2条回答
  •  别那么骄傲
    2020-12-13 09:44

    I have a longer test to try. This takes an average of 160 ns to read each line as add it to a List (Which is likely to be what you intended as dropping the newlines is not very useful.

    public static void main(String... args) throws IOException {
        final int runs = 5 * 1000 * 1000;
    
        final ServerSocket ss = new ServerSocket(0);
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Socket serverConn = ss.accept();
                    String line = "Hello World!\n";
                    BufferedWriter br = new BufferedWriter(new OutputStreamWriter(serverConn.getOutputStream()));
                    for (int count = 0; count < runs; count++)
                        br.write(line);
                    serverConn.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    
        Socket conn = new Socket("localhost", ss.getLocalPort());
    
        long start = System.nanoTime();
        BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
        String line;
    
        List responseData = new ArrayList();
        while ((line = in.readLine()) != null) {
            responseData.add(line);
        }
        long time = System.nanoTime() - start;
        System.out.println("Average time to read a line was " + time / runs + " ns.");
        conn.close();
        ss.close();
    }
    

    prints

    Average time to read a line was 158 ns.
    

    If you want to build a StringBuilder, keeping newlines I would suggets the following approach.

    Reader r = new InputStreamReader(conn.getInputStream());
    String line;
    
    StringBuilder sb = new StringBuilder();
    char[] chars = new char[4*1024];
    int len;
    while((len = r.read(chars))>=0) {
        sb.append(chars, 0, len);
    }
    

    Still prints

    Average time to read a line was 159 ns.
    

    In both cases, the speed is limited by the sender not the receiver. By optimising the sender, I got this timing down to 105 ns per line.

提交回复
热议问题