你的问题让我想知道性能。最近我一直在尽可能地使用 Guava 的 Splitter,只是因为我挖掘了语法。我从未测量过性能,所以我对四种解析样式进行了快速测试。我很快就把这些放在一起,所以请原谅风格和边缘情况正确性方面的错误。它们基于我们只对第二项和第四项感兴趣的理解。
我发现有趣的是,在解析 350MB 制表符分隔的文本文件(有四列)时,“homeGrown”(非常粗略的代码)解决方案是最快的,例如:
head test.txt
0 0 0 0
1 2 3 4
2 4 6 8
3 6 9 12
在我的笔记本电脑上运行超过 350MB 的数据时,我得到了以下结果:
- 国产:2271ms
- 番石榴分裂:3367ms
- 正则表达式:7302ms
- 标记化:3466ms
鉴于此,我想我会在大多数工作中坚持使用 Guava 的拆分器,并考虑为更大的数据集使用自定义代码。
public static List<String> tokenize(String line){
List<String> result = Lists.newArrayList();
StringTokenizer st = new StringTokenizer(line, "\t");
st.nextToken(); //get rid of the first token
result.add(st.nextToken()); //show me the second token
st.nextToken(); //get rid of the third token
result.add(st.nextToken()); //show me the fourth token
return result;
}
static final Splitter splitter = Splitter.on('\t');
public static List<String> guavaSplit(String line){
List<String> result = Lists.newArrayList();
int i=0;
for(String str : splitter.split(line)){
if(i==1 || i==3){
result.add(str);
}
i++;
}
return result;
}
static final Pattern p = Pattern.compile("^(.*?)\\t(.*?)\\t(.*?)\\t(.*)$");
public static List<String> regex(String line){
List<String> result = null;
Matcher m = p.matcher(line);
if(m.find()){
if(m.groupCount()>=4){
result= Lists.newArrayList(m.group(2),m.group(4));
}
}
return result;
}
public static List<String> homeGrown(String line){
List<String> result = Lists.newArrayList();
String subStr = line;
int cnt = -1;
int indx = subStr.indexOf('\t');
while(++cnt < 4 && indx != -1){
if(cnt==1||cnt==3){
result.add(subStr.substring(0,indx));
}
subStr = subStr.substring(indx+1);
indx = subStr.indexOf('\t');
}
if(cnt==1||cnt==3){
result.add(subStr);
}
return result;
}
请注意,通过适当的边界检查和更优雅的实现,所有这些都可能会变慢。