亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Java計(jì)算代碼段執(zhí)行時(shí)間的詳細(xì)過程

 更新時(shí)間:2023年02月07日 10:54:47   作者:你家寶寶  
java里計(jì)算代碼段執(zhí)行時(shí)間可以有兩種方法,一種是毫秒級(jí)別的計(jì)算,另一種是更精確的納秒級(jí)別的計(jì)算,這篇文章主要介紹了java計(jì)算代碼段執(zhí)行時(shí)間,需要的朋友可以參考下

前言

在日常開發(fā)功能時(shí),同一種功能可能會(huì)有多種實(shí)現(xiàn)方式。我們需要做一個(gè)取舍。

最常見的條件就是性能、可讀性、可維護(hù)性。

本篇文章,我們主要討論“性能”。

場景

假設(shè)我們現(xiàn)在需要計(jì)算一段代碼的運(yùn)行時(shí)間。

最常見的寫法是,在執(zhí)行這段代碼前,獲得一下當(dāng)前的時(shí)間戳,在執(zhí)行這段代碼后,獲取一下當(dāng)前的時(shí)間戳,然后倆時(shí)間相減,就是花費(fèi)時(shí)間了。

但有時(shí),我們需要將這段代碼執(zhí)行多次。

這種場景是,執(zhí)行的時(shí)間戳很小,沒有可比性。比如執(zhí)行一段代碼,運(yùn)行時(shí)間是 0 或者 2毫秒。

這種時(shí)候你可能會(huì)說,那就用一個(gè)for循環(huán),執(zhí)行多次,計(jì)算平均時(shí)間就好了。

問題來了,如果這種相似的操作,寫的多了呢,用的地方很多呢?

我們現(xiàn)在就需要將它給寫成一套模板,只需要簡單的填充參數(shù),調(diào)用,就能實(shí)現(xiàn)上述的功能。

代碼實(shí)現(xiàn)

MethodBody 接口定義

這個(gè)接口主要是用于填充代碼段,因此設(shè)計(jì)為函數(shù)式接口,方便調(diào)用。

package org.feng.calc;
/**
 * 運(yùn)行的方法內(nèi)容:使用Lambda
 *
 * @version V1.0
 */
@FunctionalInterface
public interface MethodBody {
    void run();
}

CalcExecuteTimeResult 運(yùn)行結(jié)果實(shí)體

package org.feng.calc;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
/**
 * 計(jì)算執(zhí)行時(shí)間的結(jié)果保存
 *
 * @version V1.0
 */
@Data
public class CalcExecuteTimeResult {
    /**
     * 執(zhí)行代碼花費(fèi)的時(shí)間
     */
    private List<Long> costTime;
    public CalcExecuteTimeResult(int size) {
        costTime = new ArrayList<>(size);
    }
}

ExecuteTemplate 執(zhí)行模板定義

package org.feng.calc;
import lombok.Getter;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
/**
 * 執(zhí)行模板
 *
 * @version V1.0
 */
public class ExecuteTemplate {
    private final List<MethodBody> methodBodyList;
    @Getter
    private CalcExecuteTimeResult calcExecuteTimeResult;
    public ExecuteTemplate() {
        this.methodBodyList = new ArrayList<>();
    }
    public void addMethod(MethodBody methodBody) {
        methodBodyList.add(methodBody);
    }
    /**
     * 執(zhí)行
     *
     * @param timeUnit  時(shí)間單位
     * @param frequency 頻次-單個(gè)方法{@link MethodBody}實(shí)例執(zhí)行的次數(shù)
     */
    void process(TimeUnit timeUnit, long frequency) {
        this.calcExecuteTimeResult = new CalcExecuteTimeResult(methodBodyList.size());
        List<Long> costTime = calcExecuteTimeResult.getCostTime();
        for (MethodBody methodBody : methodBodyList) {
            long startTime = getTime(timeUnit);
            for (int i = 0; i < frequency; i++) {
                methodBody.run();
            }
            long endTime = getTime(timeUnit);
            costTime.add(endTime - startTime);
        }
    }
    private long getTime(TimeUnit timeUnit) {
        if (!SUPPORTED_TIME_UNIT.contains(timeUnit)) {
            throw new UnsupportedOperationException("不支持的時(shí)間單位:" + timeUnit);
        }
        if (TimeUnit.NANOSECONDS.equals(timeUnit)) {
            return System.nanoTime();
        }
        return System.currentTimeMillis();
    }
    /**
     * 當(dāng)前支持的時(shí)間單位
     */
    private static final Set<TimeUnit> SUPPORTED_TIME_UNIT = Set.of(TimeUnit.MILLISECONDS, TimeUnit.NANOSECONDS);
}

CalcExecuteTimeContext 計(jì)算執(zhí)行時(shí)間上下文

package org.feng.calc;
import lombok.Setter;
import lombok.experimental.Accessors;
import java.util.concurrent.TimeUnit;
/**
 * 計(jì)算執(zhí)行時(shí)間-上下文
 *
 * @version V1.0
 */
@Setter
@Accessors(chain = true)
public class CalcExecuteTimeContext {
    private TimeUnit timeUnit;
    private Long frequency;
    private ExecuteTemplate executeTemplate;
    public CalcExecuteTimeResult run() {
        executeTemplate.process(timeUnit, frequency);
        return executeTemplate.getCalcExecuteTimeResult();
    }
    public void addMethod(MethodBody methodBody){
        executeTemplate.addMethod(methodBody);
    }
}

測(cè)試運(yùn)行

package org.feng.calc;
import java.util.concurrent.TimeUnit;
/**
 * 測(cè)試運(yùn)行
 *
 * @version v1.0
 */
public class Client {
    public static void main(String[] args) {
        // 初始化上下文:設(shè)置每個(gè)方法執(zhí)行的次數(shù),以及計(jì)算時(shí)間時(shí)使用的時(shí)間單位,執(zhí)行模板
        CalcExecuteTimeContext context = new CalcExecuteTimeContext()
                .setFrequency(2L)
                .setTimeUnit(TimeUnit.MILLISECONDS)
                .setExecuteTemplate(new ExecuteTemplate());
        context.addMethod(() -> {
            System.out.println(111);
            System.out.println(111);
            System.out.println(111);
            System.out.println(111);
            System.out.println(111);
        });
        context.addMethod(() -> {
            System.out.println(222);
            System.out.println(222);
            System.out.println(222);
            System.out.println(222);
            System.out.println(222);
        });
        // 計(jì)算得到方法運(yùn)行的結(jié)果
        CalcExecuteTimeResult executeTimeResult = context.run();
        System.out.println(executeTimeResult);
    }
}

運(yùn)行結(jié)果:

111
111
111
111
111
111
111
111
111
111
222
222
222
222
222
222
222
222
222
222
CalcExecuteTimeResult(costTime=[0, 1])

到此這篇關(guān)于Java計(jì)算代碼段執(zhí)行時(shí)間的詳細(xì)過程的文章就介紹到這了,更多相關(guān)Java代碼段執(zhí)行時(shí)間內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論