首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ByteBuffer性能

ByteBuffer性能
EN

Stack Overflow用户
提问于 2015-12-14 23:31:36
回答 1查看 424关注 0票数 0

我有一个将接收超过1000 TPS的套接字,所以我需要尽可能快的读取,在这个套接字中我读取信息,我需要构建和字符串,并检查它是否匹配正则表达式。我需要一个字符一个字符地读,这样我现在就可以把新消息发送到哪里

但我遇到了性能问题,我正在用JMeter测试它,一段时间后吞吐量开始下降。到目前为止,这是我发现的读取元素并对其进行分类的最好方法(通过char聊天),因为我知道消息新消息何时开始/结束的唯一方法是因为NULL,即下面的代码

代码语言:javascript
复制
//Keep reading info from the socket    
while (running) {
    try {
        Future<Integer> readFuture = getWorker().read(buffer);
        Integer option = readFuture.get();
        if (option > 0) {
            buffer.flip();
            //Read all the info from the buffer
            while (buffer.hasRemaining()) {
                char buf = (char) buffer.get();
                if (buf == '/') {
                    continue;
                }
                //If the info has one of those char, it's a new message, so I have to manage and keep reading
                if (buf == '\0' || buf == ' ') {
                    trace=sendMessage(trace);
                } else {
                    trace.append(buf);
                }
            }
            buffer.clear();
        } else {
            trace=sendMessage(trace);
            running = false;
            close();
        }
    } catch (Exception e) {
        //Error management 
    }
}
EN

回答 1

Stack Overflow用户

发布于 2015-12-15 02:15:45

这是一个示例,它不是最快的,但却是您可能编写的发送聊天消息的最简单代码。你可以使用NIO,事实上我是这样做的,但只有在我真正需要的时候才会这样做。

这个例子只使用了换行符结束的文本。对于二进制,我建议在每个消息之前将每个消息的大小写成一个32位的值。(可能是16位,如果你知道它们总是很小的话)

Server side codeClient side code

代码语言:javascript
复制
public static void main(String[] args) throws IOException {
    ServerSocket ss = new ServerSocket(PORT);
    while (true) {
        Socket s = ss.accept();
        new Thread(() -> {
            System.out.println("Accepted " + s);
            try {
                try (BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream(), StandardCharsets.UTF_8));
                     PrintWriter pw = new PrintWriter(new OutputStreamWriter(s.getOutputStream(), StandardCharsets.UTF_8), true)) {
                    for (String line; (line = br.readLine()) != null; )
                        handle(line, pw);
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                System.out.println("... " + s + " closed");
            }
        }).start();
    }
}

static void handle(String line, PrintWriter pw) {
    pw.println(line);
}

它们打印结果

代码语言:javascript
复制
 Throughput test wrote 44.2 MB/s
 Latency test for 100,000 TPS
 Latency distribution 50/90 99/99.9 (worst) was 528,477/1,069,998 1,163,770/1,173,065 (1,174,106) micro-seconds
 Latency test for 80,000 TPS
 Latency distribution 50/90 99/99.9 (worst) was 276,228/498,628 551,875/556,160 (556,636) micro-seconds
 Latency test for 60,000 TPS
 Latency distribution 50/90 99/99.9 (worst) was 14/22 1,759/3,031 (3,393) micro-seconds
 Latency test for 50,000 TPS
 Latency distribution 50/90 99/99.9 (worst) was 14/21 4,388/5,518 (5,641) micro-seconds
 Latency test for 40,000 TPS
 Latency distribution 50/90 99/99.9 (worst) was 14/15 22/485 (2,071) micro-seconds
 Latency test for 30,000 TPS
 Latency distribution 50/90 99/99.9 (worst) was 14/15 21/921 (3,360) micro-seconds
 Latency test for 20,000 TPS
 Latency distribution 50/90 99/99.9 (worst) was 15/19 24/46 (656) micro-seconds

由此我可以得出结论,一个线程每秒甚至不能处理80,000条短消息,但它可以很好地处理每秒60,000条短消息,并且在每秒40,000条时可以获得更稳定的结果。

这些方法的结果很好,因为它们具有非常高的TPS,实际上,在100 TPS或更低的情况下,您会看到低消息率的副作用。这种副作用是由于计时器中断和其他中断导致CPU缓存每10毫秒受到干扰,这会损害延迟,而不是这些示例中的1/ 100左右,而是每条消息。

简而言之,您必须以不同的方式优化<100Tps,因为消息速率是,所以很低,而不是因为它太高。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34270807

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档