Java正则表达式提供任何性能优势?
在Java中,当我们尝试使用正则表达式进行模式匹配时。 例如,输入一个字符串并使用正则表达式来确定它是否是数字。 如果不是,则抛出异常。 在这种情况下,我明白,使用正则表达式可以减少代码冗长,比如果我们要获取字符串的每个字符,检查它是否是数字,是否抛出异常。
但我认为正则表达式也使得这个过程更有效率。 这是真的? 在这一点上我找不到任何证据。 正则表达式如何在幕后进行比赛? 它是不是也遍历字符串并逐个检查每个字符?
为了好玩,我已经运行了这个微基准。 最后一次运行的结果(即JVM后期热身/ JIT)低于(无论如何,从一次运行到另一次运行结果都是相当一致的):
regex with numbers 123
chars with numbers 33
parseInt with numbers 33
regex with words 123
chars with words 34
parseInt with words 733
换句话说,字符是非常有效的,Integer.parseInt与char相同,如果字符串是一个数字,但是如果字符串不是数字,则非常慢。 正则表达式介于两者之间。
结论
如果将一个字符串解析为一个数字,并且您希望该字符串通常是一个数字,那么使用Integer.parseInt是最好的解决方案(高效且可读)。 如果字符串不是一个数字,那么得到的惩罚应该是低的,如果它不太频繁。
ps:我的正则表达式可能不是最优的,随时发表评论。
public class TestNumber {
private final static List<String> numbers = new ArrayList<>();
private final static List<String> words = new ArrayList<>();
public static void main(String args[]) {
long start, end;
Random random = new Random();
for (int i = 0; i < 1000000; i++) {
numbers.add(String.valueOf(i));
words.add(String.valueOf(i) + "x");
}
for (int i = 0; i < 5; i++) {
start = System.nanoTime();
regex(numbers);
System.out.println("regex with numbers " + (System.nanoTime() - start) / 1000000);
start = System.nanoTime();
chars(numbers);
System.out.println("chars with numbers " + (System.nanoTime() - start) / 1000000);
start = System.nanoTime();
exception(numbers);
System.out.println("exceptions with numbers " + (System.nanoTime() - start) / 1000000);
start = System.nanoTime();
regex(words);
System.out.println("regex with words " + (System.nanoTime() - start) / 1000000);
start = System.nanoTime();
chars(words);
System.out.println("chars with words " + (System.nanoTime() - start) / 1000000);
start = System.nanoTime();
exception(words);
System.out.println("exceptions with words " + (System.nanoTime() - start) / 1000000);
}
}
private static int regex(List<String> list) {
int sum = 0;
Pattern p = Pattern.compile("[0-9]+");
for (String s : list) {
sum += (p.matcher(s).matches() ? 1 : 0);
}
return sum;
}
private static int chars(List<String> list) {
int sum = 0;
for (String s : list) {
boolean isNumber = true;
for (char c : s.toCharArray()) {
if (c < '0' || c > '9') {
isNumber = false;
break;
}
}
if (isNumber) {
sum++;
}
}
return sum;
}
private static int exception(List<String> list) {
int sum = 0;
for (String s : list) {
try {
Integer.parseInt(s);
sum++;
} catch (NumberFormatException e) {
}
}
return sum;
}
}
我还没有技术答案,但我可以写一些代码并查看。 我不认为正则表达式是将字符串转换为数字的方式。 在很多情况下,它们可以更高效,但如果写得不好,速度会很慢。
请问,为什么你不使用: Integer.parseInt("124")
? 这将抛出NumberFormatException。 应该能够处理它,并且它将检测到一个数字直到核心Java。
关于幕后的正则表达式...
有限状态机(FSM)相当于一个正则表达式。 FSM是一种可识别语言的机器(在您的案例中)。 FSM有一个字母表,一个状态,一个初始状态,N个终止状态以及从一个状态到另一个状态的转换功能。 该字符串需要包含在字母表中(例如,ASCII)。 FSM从初始状态开始。 当你输入一个字符串时,它会根据一个函数(state,char)=>状态从一个状态移动到另一个状态。 当它达到最终状态时,你知道你的字符串是否是数字。
有关更多信息,请参阅FSM并参阅基于自动机的编程
链接地址: http://www.djcxy.com/p/15255.html上一篇: Java regular expression offers any performance benefit?
下一篇: regex vs while loops