如何快速检测是否空白字符

简介: 在Parser场景,包括SQL Parser和JSON Parser,如果更快检测空白字符时一个提升性能的关键点。笔者有多年SQL Parser和JSON Parser的经验,把我所知道的一些检测空白的方法分享给大家。## 1. 什么是空白字符如果采用json.org的标准,空白字符包括:```bash'\b' -- ASCII 8'\t' -- ASCII 9'\n' -- ASC

在Parser场景,包括SQL Parser和JSON Parser,如果更快检测空白字符时一个提升性能的关键点。笔者有多年SQL Parser和JSON Parser的经验,把我所知道的一些检测空白的方法分享给大家。

1. 什么是空白字符

如果采用json.org的标准,空白字符包括:

'\b' -- ASCII 8
'\t' -- ASCII 9
'\n' -- ASCII 10
'\f' -- ASCII 12
'\r' -- ASCII 13
' '  -- ASCII 32
AI 代码解读

2. 检测空白字符的5种方法

2.1 方法1

JDK的Character提供了isWhiteSpace方法,逻辑不能定制化,不支持上面的'\b'字符判空,但为了性能比较,也加入进来。

boolean space = Character.isWhitespace(ch);
AI 代码解读

2.1 方法2

这个常规办法,用6个并列的or判断。所有的字符检测都需要做6次判断,性能较差。

boolean space = ch == ' '
    || ch == '\n'
    || ch == '\r'
    || ch == '\f'
    || ch == '\t'
    || ch == '\b';
AI 代码解读

2.2 方法3

由于空白字符最大的是空格ASCII 32,在方法2的基础上先做一个预先检测,这样就能获得非常好的性能,但当输入的有大量空白字符\b时,就就会面临方法2的问题。fastjson 1.x ( http://github.com/alibaba/fastjson )判空用的是这个方法。

boolean space = ch <= ' '
    && (ch == ' '
        || ch == '\n'
        || ch == '\r'
        || ch == '\f'
        || ch == '\t'
        || ch == '\b');
AI 代码解读

2.3 方法4

这种算法,在JDK 17下性能有较大提升。在大量输入是非空字符时,性能并不出色。

boolean space;
switch (ch) {
    case ' ':
    case '\n':
    case '\r':
    case '\t':
    case '\b':
    case '\f':
        space = true;
        break;
    default:
        space = false;
        break;
}
AI 代码解读

2.4 方法5

通过预计算一个常量的long,然后做bitAnd判断。
fastjson2 ( https://github.com/alibaba/fastjson2 )判空用的是这个方法。

static final long SPACE = (1L << ' ') 
    | (1L << '\n') 
    | (1L << '\r') 
    | (1L << '\f') 
    | (1L << '\t') 
    | (1L << '\b');


boolean space = ch <= ' ' && ((1L << ch) & SPACE) != 0;
AI 代码解读

3. 测试环境

3.1 x86服务器

  • 使用阿里云x64当前代计算型4核8G服务器,CPU型号 Intel Xeon(Ice Lake) Platinum 8369B

3.2 ARM服务器

  • 使用阿里云ARM当前代计算型4核8G服务器,CPU型号 Ampere Altra / AltraMax

3.3 JDK

  • 下载Oracle最新的LTS版本Linux JDK
jdk1.8.0_333_x64
jdk-11.0.15.1_x64
jdk-17.0.3.1_x64
jdk1.8.0_333_aarch64
jdk-11.0.15.1_aarch64
jdk-17.0.3.1_aarch64
AI 代码解读

3.4 测试数据

{"images": [{
      "height":768,
      "size":"LARGE",
      "title":"Javaone Keynote",
      "uri":"http://javaone.com/keynote_large.jpg",
      "width":1024
    }, {
      "height":240,
      "size":"SMALL",
      "title":"Javaone Keynote",
      "uri":"http://javaone.com/keynote_small.jpg",
      "width":320
    }
  ],
  "media": {
    "bitrate":262144,
    "duration":18000000,
    "format":"video/mpg4",
    "height":480,
    "persons": [
      "Bill Gates",
      "Steve Jobs"
    ],
    "player":"JAVA",
    "size":58982400,
    "title":"Javaone Keynote",
    "uri":"http://javaone.com/keynote.mpg",
    "width":640
  }
}
AI 代码解读

4. JMH测试结果

4.1 x64测试结果

JDK8 JDK11 JDK17
方法1 1756.884 1692.215 1770.658
方法2 1911.820 1866.888 1903.105
方法3 3496.629 4228.972 3956.434
方法4 2798.679 2910.525 2876.148
方法5 3522.462 3694.007 4474.286
  • 原始数据
### jdk1.8.0_333_x64
Benchmark                                   Mode  Cnt     Score      Error   Units
SpaceCheckBenchmark.CharacterIsWhitespace  thrpt    5  1756.884 ?    2.202  ops/ms
SpaceCheckBenchmark.spaceOr                thrpt    5  1911.820 ?    5.965  ops/ms
SpaceCheckBenchmark.spaceOrPreCheck        thrpt    5  3496.629 ?  739.373  ops/ms
SpaceCheckBenchmark.spaceSwitch            thrpt    5  2798.679 ? 1024.227  ops/ms
SpaceCheckBenchmark.spaceBitAnd            thrpt    5  3522.462 ?  859.084  ops/ms

### jdk-11.0.15.1_x64
Benchmark                                   Mode  Cnt     Score     Error   Units
SpaceCheckBenchmark.CharacterIsWhitespace  thrpt    5  1692.215 ? 363.925  ops/ms
SpaceCheckBenchmark.spaceOr                thrpt    5  1866.888 ?  33.836  ops/ms
SpaceCheckBenchmark.spaceOrPreCheck        thrpt    5  4228.972 ? 212.870  ops/ms
SpaceCheckBenchmark.spaceSwitch            thrpt    5  2910.525 ? 584.406  ops/ms
SpaceCheckBenchmark.spaceBitAnd            thrpt    5  3694.007 ? 158.193  ops/ms


### jdk-17.0.3.1_x64
Benchmark                                   Mode  Cnt     Score     Error   Units
SpaceCheckBenchmark.CharacterIsWhitespace  thrpt    5  1770.658 ? 651.168  ops/ms
SpaceCheckBenchmark.spaceOr                thrpt    5  1903.105 ?  40.520  ops/ms
SpaceCheckBenchmark.spaceOrPreCheck        thrpt    5  3956.434 ? 628.745  ops/ms
SpaceCheckBenchmark.spaceSwitch            thrpt    5  2876.148 ? 127.401  ops/ms
SpaceCheckBenchmark.spaceBitAnd            thrpt    5  4474.286 ? 539.261  ops/ms
AI 代码解读

4.1 ARM测试结果

JDK8 JDK11 JDK17
方法1 911.795 785.339 1269.834
方法2 789.439 833.830 842.177
方法3 2304.419 2429.907 2146.953
方法4 880.387 1124.967 1540.419
方法5 2363.957 2392.123 2570.536
  • 原始数据
### jdk1.8.0_333_aarch64
Benchmark                                   Mode  Cnt     Score     Error   Units
SpaceCheckBenchmark.CharacterIsWhitespace  thrpt    5   911.795 ?   5.171  ops/ms
SpaceCheckBenchmark.spaceOr                thrpt    5   789.439 ? 163.867  ops/ms
SpaceCheckBenchmark.spaceOrPreCheck        thrpt    5  2304.419 ?  29.643  ops/ms
SpaceCheckBenchmark.spaceSwitch            thrpt    5   880.387 ?  63.411  ops/ms
SpaceCheckBenchmark.spaceBitAnd            thrpt    5  2363.957 ? 759.335  ops/ms

### jdk-11.0.15.1_aarch64
Benchmark                                   Mode  Cnt     Score     Error   Units
SpaceCheckBenchmark.CharacterIsWhitespace  thrpt    5   785.339 ?   5.361  ops/ms
SpaceCheckBenchmark.spaceOr                thrpt    5   833.830 ?  14.402  ops/ms
SpaceCheckBenchmark.spaceOrPreCheck        thrpt    5  2429.907 ?   9.120  ops/ms
SpaceCheckBenchmark.spaceSwitch            thrpt    5  1124.967 ? 811.435  ops/ms
SpaceCheckBenchmark.spaceBitAnd            thrpt    5  2392.123 ? 381.551  ops/ms

### jdk-17.0.3.1_aarch64
Benchmark                                   Mode  Cnt     Score     Error   Units
SpaceCheckBenchmark.CharacterIsWhitespace  thrpt    5  1269.834 ?   5.587  ops/ms
SpaceCheckBenchmark.spaceOr                thrpt    5   842.177 ?   7.969  ops/ms
SpaceCheckBenchmark.spaceOrPreCheck        thrpt    5  2146.953 ? 518.320  ops/ms
SpaceCheckBenchmark.spaceSwitch            thrpt    5  1540.419 ?  32.401  ops/ms
SpaceCheckBenchmark.spaceBitAnd            thrpt    5  2570.536 ?   2.284  ops/ms
AI 代码解读

5. 结论

综合下来,无论是x64还是aarch64,方法5性能最理想。

目录
打赏
0
0
0
0
0
分享
相关文章
|
11月前
引用 AspNetCoreRateLimit => StatusCode cannot be set because the response has already started.
引用 AspNetCoreRateLimit => StatusCode cannot be set because the response has already started.
251 0
阿里云服务器计算型c7、c7a、c8a、c8y实例区别参考
在阿里云目前的活动中,属于计算型实例规格的云服务器有计算型c7、计算型c7a、计算型c8a、计算型c8y这几个实例规格,相比于活动内的经济型e和通用算力型u1等实例规格来说,这些实例规格等性能更强,本文为大家介绍计算型c7、c7a、c8a、c8y实例区别及最新活动价格,以供参考。
阿里云服务器计算型c7、c7a、c8a、c8y实例区别参考
Springboot整合与使用log4j2日志框架【详解版】
该文介绍了如何在Spring Boot中切换默认的LogBack日志系统至Log4j2。首先,需要在Maven依赖中排除`spring-boot-starter-logging`并引入`spring-boot-starter-log4j2`。其次,创建`log4j2-spring.xml`配置文件放在`src/main/resources`下,配置包括控制台和文件的日志输出、日志格式和文件切分策略。此外,可通过在不同环境的`application.yml`中指定不同的log4j2配置文件。最后,文章提到通过示例代码解释了日志格式中的各种占位符含义。
946 0
利用深度学习优化视频压缩效率的新策略
【4月更文挑战第2天】在数字媒体时代,视频数据占据了互联网流量的主导地位。随着高清、4K甚至8K视频内容的兴起,传统的视频压缩技术面临着巨大挑战。本文提出了一种基于深度学习的视频压缩优化方法,通过训练一个深度神经网络来预测视频帧间的残差信息,实现更高效的压缩。实验结果表明,该策略在保证视频质量的同时,能够显著提高压缩比,减少传输带宽和存储空间的需求。
205 0
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等

登录插画

登录以查看您的控制台资源

管理云资源
状态一览
快捷访问