之前写了文章介绍Groovy关键字as
,我个人是十分推荐使用,特别在基础类型数据转换场景下,as
关键字能够随心所欲将数据转换成我们需要的类型。但在实际使用过程中,由于没看到具体实现,也难以对as
关键字的性能有个了解。所以今天准备测试几种我经常使用的场景进行as
关键字的性能测试。
这次我准备使用Java微基准测试神器JMH初探来进行基准测试,自从用上了JMH
,就再也没有自己写过基准测试用例了。十分推荐。
String转double
这个是非常常用的,还有一个类似的String转int,由于极其相似就不再测试了。其实结论大差不差。
下面是我的测试用例,分成了两部分,一部分Groovy类,用于实现各种不同方法,一部分是JMH的内容。原因是我还没有找到JMH完美兼容Groovy的方法。
Groovy类:
代码语言:javascript复制
class JmhG {
static double groovy(String str) {
str as double
}
static double java(String str) {
Double.valueOf(str);
}
static double java2(String str) {
str.toBigDecimal()
}
}
JMH测试Case:
代码语言:javascript复制
import com.funtester.frame.SourceCode;
import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.results.format.ResultFormatType;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;
import java.util.concurrent.TimeUnit;
@BenchmarkMode(Mode.Throughput)
@Warmup(iterations = 2, time = 5, timeUnit = TimeUnit.SECONDS)
@Measurement(iterations = 5, time = 10, timeUnit = TimeUnit.SECONDS)
@Threads(2)
@Fork(1)
@State(value = Scope.Thread)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public class JmhT extends SourceCode {
@Param(value = {"13323222320", "2323230.2323233232", "532873873828382738201"})
private String str;
@Benchmark
public void groovy() {
JmhG.groovy(str);
}
@Benchmark
public void java() {
JmhG.java(str);
}
@Benchmark
public void javaForce() {
JmhG.java2(str);
}
public static void main(String[] args) throws RunnerException {
Options options = new OptionsBuilder()
.include(JmhT.class.getSimpleName())
.result("result.json")
.resultFormat(ResultFormatType.JSON)
.forks(1)
.threads(2)
.warmupIterations(1)
.warmupBatchSize(1)
.measurementIterations(2)
.measurementBatchSize(2)
.build();
new Runner(options).run();
}
}
测试结果:
代码语言:javascript复制
Benchmark (str) Mode Cnt Score Error Units
JmhT.groovy 13323222320 thrpt 2 9314.268 ops/ms
JmhT.groovy 2323230.2323233232 thrpt 2 4219.366 ops/ms
JmhT.groovy 532873873828382738201 thrpt 2 4442.363 ops/ms
JmhT.java 13323222320 thrpt 2 19418.404 ops/ms
JmhT.java 2323230.2323233232 thrpt 2 5679.708 ops/ms
JmhT.java 532873873828382738201 thrpt 2 6331.530 ops/ms
JmhT.javaForce 13323222320 thrpt 2 27996.119 ops/ms
JmhT.javaForce 2323230.2323233232 thrpt 2 3400.895 ops/ms
JmhT.javaForce 532873873828382738201 thrpt 2 1614.033 ops/ms
从结果看出来,Java自带的方法Double.valueOf(str)
性能最好,Groovy关键字as
次之,而org.codehaus.groovy.runtime.StringGroovyMethods#toBigDecimal
这个方法的性能有点飘忽不定,在int类型字符串情况下,它性能最高。在较长小数点情况下,又稍逊一筹,到了long类型数据直接崩了。各位可以根据使用场景自行选择。
数字转String
这个用得少,通常直接使用Java自带的加一个空字符串实现。不过趁着这次测试看一下各方面不同的性能表现。
Groovy方法类:
代码语言:javascript复制
class Jmh {
static String groovy(double number) {
number as String
}
static String java(double number) {
number ""
}
static String java2(double number) {
number.toString()
}
}
JMH的测试Case就不发了,复用上面的,下面是测试结果:
代码语言:javascript复制Benchmark (num) Mode Cnt Score Error Units
JmhT.groovy 13323222320 thrpt 2 5533.081 ops/ms
JmhT.groovy 2323230.2323233232 thrpt 2 2713.348 ops/ms
JmhT.groovy 532873873828382738201 thrpt 2 2845.852 ops/ms
JmhT.java 13323222320 thrpt 2 7226.492 ops/ms
JmhT.java 2323230.2323233232 thrpt 2 2572.057 ops/ms
JmhT.java 532873873828382738201 thrpt 2 2652.787 ops/ms
JmhT.javaForce 13323222320 thrpt 2 19337.224 ops/ms
JmhT.javaForce 2323230.2323233232 thrpt 2 3979.556 ops/ms
JmhT.javaForce 532873873828382738201 thrpt 2 3940.559 ops/ms
可以看出Groovy方法性能明显弱于Java的视线,而两种Java实现性能相差无几。这里建议追求极限性能的使用Java的java.lang.Double#toString()
或者java.lang.Double#toString(double)
这俩其实是一个方法。
double转int
下面分享一下数字类型之间相互转换,以double转int为例。
Groovy方法类:
代码语言:javascript复制class JmhG {
static int groovy(double d) {
d as int
}
static int java(double d) {
(int) d
}
}
JMH测试方法部分内容:
参数化做了点修改,其他内容不变。
代码语言:javascript复制 @Param(value = {"13.20", "2323230.2323233232"})
private double num;
下面是测试结果:
代码语言:javascript复制Benchmark (num) Mode Cnt Score Error Units
JmhT.groovy 13.20 thrpt 2 16441.947 ops/ms
JmhT.groovy 2323230.2323233232 thrpt 2 13305.805 ops/ms
JmhT.java 13.20 thrpt 2 846022.670 ops/ms
JmhT.java 2323230.2323233232 thrpt 2 861913.384 ops/ms
结论差不多,Groovy关键字as
的性能更差了。几十倍的差距已经无法直视,后面处理脚本层面会用到groovy关键字as
,框架部分和业务部分都会避免使用as
关键字了。
结论
结尾放一下Groovy关键字as
的总结陈词。
Groovy是一种基于JVM的动态语言,它可以与Java平滑地集成,支持Java的语法和库,并且具有更高的灵活性和易用性。在Groovy中,as是一个关键字,它用于类型转换和类型推断。
在Groovy中,as关键字用于将一个对象转换为指定类型的对象。例如,可以使用as关键字将一个字符串转换为整数,或将一个Map转换为JSON字符串。as关键字还可以用于类型推断,即根据上下文推断出对象的类型。例如,在Groovy中,可以使用def关键字定义一个变量,然后根据赋值语句自动推断出变量的类型。
as关键字的用途有以下几点:
- 类型转换:as关键字可以将一个对象转换为指定类型的对象,方便程序员进行类型转换操作。
- 类型推断:as关键字可以根据上下文推断出对象的类型,简化了变量定义和类型转换的代码。
- 继承和多态:as关键字可以用于继承和多态的场景,比如将一个子类对象转换为父类对象或将一个接口对象转换为实现类对象。
总之,as关键字是Groovy语言的一个重要特性,它可以帮助程序员更方便地进行类型转换和类型推断操作,提高代码的可读性和可维护性,同时也支持继承和多态的特性,方便程序员进行面向对象编程。
FunTester原创专题推荐~~
- FunTester宣言(ChatGPT版)
- 2021年原创合集
- 2022年原创合集
- 接口功能测试专题
- 性能测试专题
- Groovy专题
- Java、Groovy、Go、Python
- 单测&白盒
- FunTester社群风采
- 测试理论鸡汤
- FunTester视频专题
- 案例分享:方案、BUG、爬虫
- UI自动化专题
- 测试工具专题
-- By FunTester