飞镖高效的弦乐处理技术?

时间:2014-02-27 12:20:54

标签: string dart

我以name:key:dataLength:data的格式编码,这些字符串通常可以链接在一起。例如"aNum:n:4:9879aBool:b:1:taString:s:2:Hi"这会映射到一个类似的对象:

{
  aNum: 9879,
  aBool: true,
  aString: "Hi"
}

我有一种解析这种格式的字符串的方法,但是我不确定是否使用substring是处理字符串的最有效方法,是否有一种更有效的方法来处理字符串时尚(反复砍掉前面部分):

Map<string, dynamic> fromString(String s){
  Map<String, dynamic> _internal = new Map();
  int start = 0;
  while(start < s.length){
    int end;
    List<String> parts = new List<String>(); //0 is name, 1 is key, 2 is data length, 3 is data
    for(var i = 0; i < 4; i++){
      end = i < 3 ? s.indexOf(':') : num.parse(parts[2]);
      parts[i] = s.substring(start, end);
      start = i < 3 ? end + 1 : end;
    }
    var tranType = _tranTypesByKey[parts[1]]; //this is just a map to an object which has a function that can convert the data section of the string into an object
    _internal[parts[0]] = tranType._fromStr(parts[3]);
  }
  return _internal;
}

2 个答案:

答案 0 :(得分:1)

我会尝试s.split(':')并处理结果列表。 如果你做了很多这样的操作,你应该考虑创建基准测试,尝试不同的技术并进行比较。

如果你仍然需要这一行

 s = i < 3 ? s.substring(idx + 1) : s.substring(idx);

我会避免在每次迭代中创建一个新的子字符串,而只是跟踪next位置。

答案 1 :(得分:1)

您必须确定性能相对于代码的可读性和可维护性的重要程度。

那就是说,你不应该反复切断琴弦的头部。这保证是低效的 - 你的字符串中的记录数量需要时间是二次的,只需要创建那些尾部字符串。

对于解析每个字段,您可以避免在长度和类型字段上执行子字符串。对于长度字段,您可以自己构建数字:

int index = ...;
// index points to first digit of length.
int length = 0;
int charCode = source.codeUnitAt(index++);
while (charCode != CHAR_COLON) {
   length = 10 * length + charCode - 0x30;
   charCode = source.codeUnitAt(index++);
}
// index points to the first character of content.

由于长度通常是小整数(小于2 <&lt; 31),因此这可能比创建子字符串并调用int.parse更有效。

类型字段是单个ASCII字符,因此您可以使用codeUnitAt来获取其ASCII值而不是创建单字符字符串(然后您的内容解释查找将需要打开字符代码而不是字符串)。

对于解析内容,您可以传递源字符串,启动索引和长度,而不是创建子字符串。然后布尔解析器也可以只读取代码单元而不是单例字符串,字符串解析器只能创建子字符串,数字解析器也可能必须创建子字符串并调用double.parse。

如果Dart有一个double.parseSubstring(source,[int from = 0,int to])可以将子字符串解析为double而不创建子字符串,那将会很方便。