0

I'm try to send data through socket in java, there are one server and multiple client, and I have a class called "Value":

public class Value<T extends Comparable<T>> implements Comparable<Value<T>> {
    public T value;
    public String result;

    public Value(T value, String result) {
        this.value = value;
        this.result = result;
    }

    public int compareTo(Value<T> v) {
        return value.compareTo(v.value);
    }
}

In server, I have a large array of Value and a hashmap to record result frequency which were send to previous client, and I want to send that to each client, the code like this:

HashMap<String, Integer> frequency = new HashMap<>();
//assume all result are exists in the frequency's key

for (Client client: clients) {
    for (String key : frequency.keySet()) {
        client.bufferedWriter.write(key + ":" + frequency.get(key))
        client.bufferedWriter.newLine();
    }

    for (int i = startIndex; i < endIndex; i++) {
        client.bufferedWriter.write(values[i].value + "," + values[i].result)
        client.bufferedWriter.newLine();
        frequency.replace(values[i].result, frequency.get(values[i].result) + 1)
    }
    client.bufferedWriter.flush();
}

Each client will receive different values. For example, I have 2 client and 10 size of values, the first client will receive values from 0 to 4 , and the second client will receive frequency info of first client taken and values from 5 to 9. Maybe it couldn't make it parallel because it is sequential.

The code as above in my algorithm, it take me about 5 seconds. How can I write that data faster and do not use nio?

hua
  • 169
  • 9
  • 2
    Do one thread per client using a `ThreadPoolExecutor` – julien.giband May 10 '22 at 11:33
  • 4
    As a beginning you are converting the values to bytes for every client. You should only have to do all that work once. Then you could use multiple threads to send in parallel. If you can change from TCP to UDP with multicast you could get away with a single send operation too, but that is probably not realistic. – ewramner May 10 '22 at 11:35
  • 1
    Why *not* use NIO? [It's not that difficult](https://stackoverflow.com/questions/3895461/non-blocking-sockets). – Philipp May 10 '22 at 11:40
  • @julien.giband I edited my post, this code have sequential, so I think it can not using thread to do it. – hua May 10 '22 at 12:46
  • @ewramner As you see after my edit, every value will send to only one client, so I can not convert one of Value to prepare to send another client – hua May 10 '22 at 12:49
  • @Philipp Because I want make it faster in a simple way, if there are not any simple way to do it, I will do it in NIO. – hua May 10 '22 at 12:50
  • Avoid excessive use of `flush` - let `bufferedWriter` decide when to flush, as `close()` or single `flush()` at the end will have same effect. – DuncG May 10 '22 at 13:20
  • If data sent to one client depends on what was sent to other clients, then there"s nothing you can do. You're using a BufferedWriter, flushing it only once you're done with one client. The only thing you could adjust on the network side is the buffer size, but I doubt it will make any difference. – julien.giband May 10 '22 at 13:42
  • @DuncG I do flush() once after all data wrote, is it excessive? – hua May 10 '22 at 14:13
  • I'm curious to know how long this takes if you replace the real sockets with https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/io/OutputStream.html#nullOutputStream()? You are focusing on the network time, but I wonder how much time is really spent preparing rather than sending the data. Make the bufferedWriter write to a nullOutputStream and test! – ewramner May 10 '22 at 14:19
  • @ewramner sure, I'll try it tomorrow, thanks. – hua May 10 '22 at 14:39
  • @hua Your code shows `flush` per iteration, not once at the end. Whether that makes a difference rather depends on size of the data per iteration, and the number of iterations. – DuncG May 13 '22 at 15:34
  • @DuncG For each client, I do ```flush``` once, not do it in every values[] after write. – hua May 14 '22 at 19:38
  • @hua Please ignore my comments as I've overlooked your use of one writer per client (assuming they are set to different values). – DuncG May 14 '22 at 19:46

0 Answers0