我正在开发基于
Java的二进制数据下载器.该数据通过基于文本的协议(UU编码)传送.对于网络任务,使用netty库.二进制数据由服务器拆分为数千个小数据包,并发送给客户机(即Java应用程序).
每当收到新消息(数据)时,从netty我收到一个ChannelBuffer对象.现在我需要处理这些数据,除了其他任务,我需要检查来自服务器的包的标题(如HTTP状态行).为此,我调用ChannelBuffer.array()来接收一个byte []数组.这个数组我可以通过新的String(byte [])转换成一个字符串,并且容易地检查(例如比较)其内容(再次,与HTTP中的“200”状态消息的比较).
我正在编写的软件正在使用多个线程/连接,以便从并行的netty接收多个数据包.
这通常工作正常,但在分析应用程序时,我注意到,当与服务器的连接良好并且数据进入速度非常快时,这种转换为String对象似乎是一个瓶颈.在这种情况下,cpu的使用率接近100%,根据分析器,调用这个String(byte [])构造函数花了很多时间.
我搜索了一个更好的方法从ChannelBuffer获取到一个String,并注意到前者也有一个toString()方法.但是,该方法甚至比String(byte [])构造函数慢.
所以我的问题是:有没有人知道一个更好的替代方案来实现我在做什么?
解决方法
也许你可以完全跳过String转换?您可以使用常量来保存比较值的字节数组,并检查数组到数组而不是String-to-String.
String http200 = "200"; // byte[] -> String conversion happens every time String input = new String(ChannelBuffer.array()); return input.equals(http200);
也许这更快:
// Ideally only convert String->byte[] once. Store these // arrays somewhere and look them up instead of recalculating. final byte[] http200 = "200".getBytes("UTF-8"); // Select the correct charset! // Input doesn't have to be converted! byte[] input = ChannelBuffer.array(); return Arrays.equals(input,http200);