在Scala中,我收到一条UDP消息,最后得到一个DatagramPacket,其缓冲区包含包含该消息的Array [Byte]。此消息是所有ASCII字符,是完全固定长度的字段,其中一些是数字,其他单个字符或字符串。从消息数据中解析这些字段的最快方法是什么?
例如,假设我的消息具有以下格式:
2 bytes - message type, either "AB" or "PQ" or "XY"
1 byte - status, either a, b, c, f, j, r, p or 6
4 bytes - a 4-character name
1 byte - sign for value 1, either space or "-"
6 bytes - integer value 1, in ASCII, with leading spaces, eg. " 1234"
1 byte - sign for value 2
6 bytes - decimal value 2
所以消息可能看起来像
ABjTst1 5467- 23.87
消息类型“AB”,状态“j”,名称“Tst1”,值1是5467,值2是-23.87
到目前为止我所做的是获取数组message: Array[Byte]
,然后从中获取切片,
比如
val msgType= new String(message.slice(0, 2))
val status = message(2).toChar
val name = new String(message.slice(3, 7))
val val1Sign = message(7).toChar
val val1= (new String(message.slice(8, 14)).trim.toInt * (if (val1Sign == '-') -1 else 1))
val val2Sign = message(14).toChar
val val2= (new String(message.slice(15, 21)).trim.toFloat * (if (val2Sign == '-') -1 else 1))
当然,重用的功能,例如解析数字,通常会进入函数。
这种技术很简单,但如果速度很重要,有没有更好的方法呢?
答案 0 :(得分:2)
编写自己的字节数组到基元的转换会稍微提高速度(如果你真的需要速度),因为它会避免产生额外的String
对象。此外,您应该使用String
构造函数
String(byte[] bytes, int offset, int length)
避免制作额外的副本。
答案 1 :(得分:0)
我没有进行性能测试的数据,但也许你有?您是否尝试使用预编译模式进行模式匹配?
评论中的数字列举了与小组相对应的开始数据:
// 12 3 4 5 6 7 8 9 10
val pattern = Pattern.compile ("((AB)|(PQ)|(XY))([abcfjrp6])(.{4})([- ])( {0,6}[0-9]{0,6})([- ])([ 0-9.]{1,6})")
//
def msplit (message: String) = {
val matcher = pattern.matcher (message)
if (matcher.find ())
List (1, 5, 6, 7, 8, 9, 10).foreach (g => println (matcher.group(g)))
}
val s = "ABjTst1 5467- 23.87"
msplit (s)
模式/匹配器当然是Javaland - 也许你会找到一个带有“...”的更多scala-way解决方案.r
结果:
AB
j
Tst1
5467
-
23.87