-3

What is the fastest way of sending array of 1000 bytes down the TCP Socket using Java? And how to measure it?

If my code that sends 1000 bytes arrya 25_000 times to "localhost" of the same machine would the measurement be fair?

How to achieve the fastest transfer rate?

ByteBuffer buffer = ByteBuffer.allocateDirect( 1000 );

SocketChannel clientSocketChannel = SocketChannel.open( new InetSocketAddress( "localhost", 8888 ) );
clientSocketChannel.socket().setTcpNoDelay( true );

// empty array of bytes
byte[] array = new byte[BUFFER_SIZE];

    for ( int i = 0; i < 25_000; i++ ) {
        buffer.put( array );
        buffer.flip();
        long start = System.nanoTime();

        // ==========================================
        do {
            int len = clientSocketChannel.write( buffer );
            if (len < 0)
                throw new EOFException();
        } while (buffer.hasRemaining());
        // ==========================================

        long elapsed = System.nanoTime() - start;
        System.out.println( i + ":\t" + elapsed );
        buffer.flip();
    }
    System.out.println( "Client: finished" );

I get these numbers during execution:

14669:  14543
14670:  62877
14671:  14971
14672:  13687
14673:  70576
14674:  20104
14675:  16254
14676:  60311
14677:  15826
14678:  15826
14679:  18820
14680:  13688
14681:  12832
14682:  12832
14683:  14115
14684:  12831
14685:  12832
14686:  14971
14687:  4705
14688:  4277
14689:  4278
14690:  4277
14691:  3849
14692:  4705
14693:  4706
14694:  4278
14695:  4705
14696:  4277
14697:  4277
14698:  4705
14699:  3849
14700:  4277
14701:  4277

so for 100 iterations it goes faster - then goes back to

15067:  14115
15068:  16254
15069:  19248
15070:  13687
15071:  13259
15072:  14115
15073:  14970
15074:  15827
15075:  14543
15076:  16682
15077:  14116
15078:  16254
15079:  14543
15080:  16253

iperf utility shows me that loppback can transfer 200 MBytes per second. That is approx 4 microseconds per 1000 bytes. So durign execution of my program transfer rate indeed approcahes this rate - but drops from time to time to 14-15 microseconds per 1000 bytes message. There is no JIT involved here as JIT is happening duirng first 10.000 iterations. No class loading, no garbage collection

kachanov
  • 2,696
  • 2
  • 21
  • 16
  • udp is generally faster than tcp. – Elliott Frisch Dec 27 '15 at 07:13
  • 1
    Do you have an actual problem? Is your current transfer rate too slow? What do you consider to be a "fair measurement", and are you not achieving it? – Vince Dec 27 '15 at 07:29
  • yes - the actual problem: to send 1000 bytes down the wire - to TCP Socket. – kachanov Dec 27 '15 at 07:33
  • @ElliottFrisch - the task is to send usng TCP not UDP. I know it is faster to send using UDP but that's not what I was asking – kachanov Dec 27 '15 at 07:34
  • That's not a problem, that's a request. StackOverflow is for programming problems. Do you not know how to send bytes via a socket? Have you even tried anything yet? For all you know, you could be doing it the fastest way... Which brings me back to: Is your current transfer rate too slow? What do you consider to be a fair measurement? – Vince Dec 27 '15 at 07:36
  • 1
    Just to clarify, the [tour](http://stackoverflow.com/tour) states "*Focus on questions about **an actual problem you have faced**. Include details about **what you have tried**.*" - just trying to follow standards. It's what keeps this site from turning to rubish. If you feel it should be any other way, there is a [meta site](http://meta.stackoverflow.com) which you can post a discussion. – Vince Dec 27 '15 at 07:45
  • @Vince Emigh - I'm facing the actual problem of sending 1000 bytes of data in byte array down the wire using TCP Socket in a FASTEST POSSIBLE WAY. – kachanov Dec 27 '15 at 09:00
  • @kachanov If you can't tell by the downvotes, that is not a problem. It is a request - something you wish to do, not something preventing you from progressing on your project. It is not a problem you are facing. I read it perfectly fine the first time.. How could we possibly help if you don't even define what qualifies as a fair measurement to you? It's as if you are asking before you have even tried anything. That's not how this site works.. If you are not achieving the transfer rate you want, specify your current transfer rate and what you wish for it to be. – Vince Dec 27 '15 at 09:01
  • @VinceEmigh - that's what preventing me from progressing in my project - HOW TO SEND 1000 Byte array as fast as possible. the provided sample of teh code shows results down to 2 microseconds. But that result is not consistent. Is there way to send these bytes FASTER? or 2 microseconds is the limt? – kachanov Dec 27 '15 at 09:08
  • It depends a lot on your medium. You speak about wire, then I guess you use local wire ethernet ? to do faster, you could change this technology. 1 you can loopback (localhost): it would be a lot faster. 2 there are other local network technologies – guillaume girod-vitouchkina Dec 27 '15 at 09:20
  • If you do your tests on the same machine, and try to load it at maximum, of course, the measurement wont be fair ! – guillaume girod-vitouchkina Dec 27 '15 at 09:25
  • Finally, some code and a current rate.. 2 microseconds is very fast (.001 of a millisecond), I really don't see how that could be a problem.. But since you are implying that it is, what is the rate you wish to achieve? – Vince Dec 27 '15 at 09:25
  • @guillaumegirod-vitouchkina - I use very fast machine and it is not loaded to the maximum by this code. – kachanov Dec 27 '15 at 09:33
  • @VinceEmigh - 500 nanoseconds – kachanov Dec 27 '15 at 09:34
  • @kachanov I doubt you'd be able to reach that using Java, if not already able to reach it via a direct buffer. Must this program be in Java? Keep in mind that native calls are performed due to Java running on a VM. These calls to native code could drag down performance. Chances are, you need to get "closer to the metal", especially if you want minimal CPU time consumpsion from your application on your machine. – Vince Dec 27 '15 at 09:38
  • @VinceEmigh - I suggest you to execute the code and put the results of last 100 executions into Excel and to draw a plot - you will see an interesting pattern – kachanov Dec 27 '15 at 10:04
  • Have you tried benchmarking with JIT optimizations disabled? Does your machine manage other processes? As you can see, there are times where it also jumps up to around x4 the average (from 15k to 60k), so things like runtime optimizations and context switching could be affecting your results. Micro-benchmarking in Java [requires some extra steps](http://stackoverflow.com/a/513259/2398375). You may need to get closer to the machine to achieve the results you want, and Java is not a good language for such. Is it mandatory that you use Java? – Vince Dec 27 '15 at 10:16
  • @VinceEmigh iperf utility shows me that loppback can transfer 200 MBytes per second. That is approx 4 microseconds per 1000 bytes. So durign execution of my program transfer rate indeed approcahes this rate - but drops from time to time to 14-15 microseconds per 1000 bytes message. There is no JIT involved here as JIT is happening duirng first 10.000 iterations. No class loading, no garbage collection – kachanov Dec 27 '15 at 11:50

1 Answers1

0

Microbenchmarking is providing false results. If we meausre not time of each iteration but time of 1000 iterations divided by 1000 we will get more accurate results

kachanov
  • 2,696
  • 2
  • 21
  • 16