Java Kotlin double类型比较操作

2018-12-31  本文已影响0人  鹅鹅鹅_

Java

Java中double的比较操作简单靠谱的有两种
1、Double.valueOf(0.0).compareTo(0.0)
2、BigDecimal.valueOf(0.0).compareTo(BigDecimal.Zero)

注意,在java中两个double相等比较不能用==

Kotlin

Java中double的比较操作简单靠谱的有三种
1、0.0.compareTo(0.0)
2、0.0 == 0.0
3、BigDecimal.valueOf(0.0).compareTo(BigDecimal.Zero)

注意,在Kotlin中两个double相等比较可以用==

那么他们的效率如何呢?本文使用JMH来做基准测试。
Java JMH代码Git
Kotlin JMH代码Git

1、Java测试代码

package jmh.benchmarks;
import org.openjdk.jmh.annotations.*;
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 org.openjdk.jmh.runner.options.TimeValue;

import java.math.BigDecimal;
import java.util.concurrent.TimeUnit;

@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
@State(Scope.Thread) //Thread: 该状态为每个线程独享。
public class JavaBasicBenchmark {
    @Benchmark
    public void doubleCompare() {
        boolean b = Double.valueOf("0.00").compareTo(0.0) == 0;
    }

    @Benchmark
    public void BigdecimalCompare() {
        boolean b = BigDecimal.valueOf(Double.valueOf("0.00")).compareTo(BigDecimal.ZERO) == 0;
    }

    public static void main(String[] args) throws RunnerException {
        Options opt = new OptionsBuilder()
                .include(JavaBasicBenchmark.class.getSimpleName()) //benchmark 所在的类的名字,注意这里是使用正则表达式对所有类进行匹配的
                .forks(2) //进行 fork 的次数。如果 fork 数是2的话,则 JMH 会 fork 出两个进程来进行测试
                .warmupIterations(2) //预热的迭代次数
                .warmupTime(TimeValue.valueOf("3"))
                .measurementIterations(5) //实际测量的迭代次数
                .measurementTime(TimeValue.valueOf("3"))
                .build();

        new Runner(opt).run();
    }
}

测试结果。将double转为Double然后使用compareTo效率更高

Benchmark                             Mode  Cnt  Score   Error  Units
JavaBasicBenchmark.BigdecimalCompare  avgt   10  0.081 ± 0.006  us/op
JavaBasicBenchmark.doubleCompare      avgt   10  0.031 ± 0.003  us/op

2、Kotlin测试代码

package jmh.benchmarks

import org.openjdk.jmh.annotations.*
import org.openjdk.jmh.runner.Runner
import org.openjdk.jmh.runner.options.OptionsBuilder
import org.openjdk.jmh.runner.options.TimeValue
import java.math.BigDecimal
import java.util.concurrent.TimeUnit

/**
 * Created by tony on 2018-12-10.
 */
@BenchmarkMode(Mode.AverageTime) // 基准测试的模式,采用整体吞吐量的模式
@OutputTimeUnit(TimeUnit.MICROSECONDS) // 基准测试结果的时间类型
@State(Scope.Thread)
open class KotlinBasicBenchmark {

    @Benchmark
    fun doubleEqual() {
        val b = "0.00".toDouble() == 0.0

    }

    @Benchmark
    fun doubleCompare() {
        val b = "0.00".toDouble().compareTo(0) == 0
    }

    @Benchmark
    fun double2BigDecialCompare() {
        val b = BigDecimal("0.00".toDouble()).compareTo(BigDecimal.ZERO) == 0
    }

    companion object {
        @JvmStatic
        fun main(args: Array<String>) {

            val options = OptionsBuilder()
                    .include(KotlinBasicBenchmark::class.java.simpleName)
                    .forks(2) //进行 fork 的次数。如果 fork 数是2的话,则 JMH 会 fork 出两个进程来进行测试
                    .warmupIterations(2) //预热的迭代次数
                    .warmupTime(TimeValue.valueOf("3"))
                    .measurementIterations(5) //实际测量的迭代次数
                    .measurementTime(TimeValue.valueOf("3"))
                    .build()
            Runner(options).run()
        }
    }
}

测试结果。直接使用==判断相等性效率最高

Benchmark                                     Mode  Cnt  Score   Error  Units
KotlinBasicBenchmark.double2BigDecialCompare  avgt   10  0.072 ± 0.048  us/op
KotlinBasicBenchmark.doubleCompare            avgt   10  0.075 ± 0.015  us/op
KotlinBasicBenchmark.doubleEqual              avgt   10  0.036 ± 0.027  us/op
上一篇下一篇

猜你喜欢

热点阅读