自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

我們一起聊聊對象與 Map 轉(zhuǎn)換性能優(yōu)化方案

開發(fā) 前端
通過將 ObjectMapper? 設(shè)計為單例模式,我們可以顯著提升性能。在整個項目中只需創(chuàng)建一個 ObjectMapper 實例,避免了每次使用時重新創(chuàng)建對象所帶來的開銷。這種方法不僅提高了性能,還簡化了代碼管理和減少了內(nèi)存消耗。

前言

有粉絲提到每次都需要new一個ObjectMapper對象,并且提到性能壓測。

Person person = new Person();
person.setAge(18);
person.setOpenid("123456");
person.setName("一安");
person.setSubName("公眾號");

System.out.println(bean2Map(person));

public static Map<String, Object> bean2Map(Object object) {
    ObjectMapper objectMapper = new ObjectMapper();
    return objectMapper.convertValue(object, new TypeReference<Map<String, Object>>() {
    });
}

改造

首先,我們將使用 Java Microbenchmark Harness (JMH) 對這段代碼進(jìn)行基準(zhǔn)測試,以便大家對其性能有一個直觀的了解。

圖片圖片

上圖是一個典型的JMH程序執(zhí)行的內(nèi)容。通過開啟多個進(jìn)程,多個線程,首先執(zhí)行預(yù)熱,然后執(zhí)行迭代,最后匯總所有的測試數(shù)據(jù)進(jìn)行分析。在執(zhí)行前后,還可以根據(jù)粒度處理一些前置和后置操作。

JMH 是 Java 語言的微基準(zhǔn)測試框架,用于準(zhǔn)確、可靠地測量和評估Java代碼的性能。它是由OpenJDK團隊開發(fā)的,專門針對Java應(yīng)用程序的性能測試和基準(zhǔn)測試。通過JMH 可以對多個方法的性能進(jìn)行定量分析。比如,當(dāng)要知道執(zhí)行一個函數(shù)需要多少時間,或者當(dāng)對一個算法有多種不同實現(xiàn)時,需要選取性能最好的那個。

依賴引入

<!-- JMH核心代碼 -->
<dependency>
    <groupId>org.openjdk.jmh</groupId>
    <artifactId>jmh-core</artifactId>
    <version>1.35</version>
</dependency>

<!-- JMH注解相關(guān)依賴 -->
<dependency>
    <groupId>org.openjdk.jmh</groupId>
    <artifactId>jmh-generator-annprocess</artifactId>
    <version>1.35</version>
</dependency>

注解說明

BenchmarkMode

名稱

解釋

單位

Mode.Throughput

operations per unit of time.(單位時間執(zhí)行的次數(shù))

ops/time

Mode.AverageTime

average time per per operation(每個方法執(zhí)行的平均時間)

time/op

Mode.SampleTime

samples the time for each operation.(每個方法執(zhí)行的時間)

time

Mode.SingleShotTime

measures the time for a single operation.(單個的執(zhí)行時間)


All

all the benchmark modes. (上面所有都執(zhí)行一次)


OutputTimeUnit

統(tǒng)計的時間單位

Warmup、Measurement

名稱

解釋

iterations

預(yù)熱次數(shù)

time

預(yù)熱時間

timeUnit

預(yù)熱時間單位

batchSize

同時預(yù)熱

State

名稱

解釋

Benchmark

所有測試共享線程。做多線程的時候使用

Group

每一組中共享線程

Thread

每一個方法或者類共享線程

Fork

進(jìn)行次數(shù),如果 fork 數(shù)是2的話,則 JMH 會 fork 出兩個進(jìn)程來進(jìn)行測試

Benchmark

表示該方法是需要進(jìn)行 benchmark 的對象,用法和 JUnit 的 @Test 類似

測試驗證

@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.SECONDS)
@State(Scope.Thread)
@Fork(1)
@Warmup(iterations = 5, time = 1)
@Measurement(iterations = 3, time = 1)
public class JsonJMHTest {


    @Benchmark
    public static Map<String, Object> bean2Map() {
        Person person = new Person();
        person.setAge(18);
        person.setOpenid("123456");
        person.setName("一安");
        person.setSubName("公眾號");

        ObjectMapper objectMapper = new ObjectMapper();
        return objectMapper.convertValue(person, new TypeReference<Map<String, Object>>() {
        });
    }

    @Benchmark
    public static <T> T map2Bean() {
        Map<String, Object> map = new HashMap();
        map.put("age", 18);
        map.put("openid", "123456");
        map.put("name", "一安");
        map.put("subName", "公眾號");

        ObjectMapper objectMapper = new ObjectMapper();
        return (T) objectMapper.convertValue(map, Person.class);
    }

    public static void main(String[] args) throws RunnerException {
        Options opt = new OptionsBuilder()
                .include(JsonJMHTest.class.getSimpleName())
                .build();
        new Runner(opt).run();
    }

測試結(jié)果:

# Fork: 1 of 1
# Warmup Iteration   1: 4121.577 ops/s
# Warmup Iteration   2: 10599.791 ops/s
# Warmup Iteration   3: 1945.716 ops/s
# Warmup Iteration   4: 7284.198 ops/s
# Warmup Iteration   5: 8161.620 ops/s
Iteration   1: 841.544 ops/s
Iteration   2: 25483.108 ops/s
Iteration   3: 70902.482 ops/s


Result "org.example.JsonJMHTest.map2Bean":
  32409.045 ±(99.9%) 648386.677 ops/s [Average]
  (min, avg, max) = (841.544, 32409.045, 70902.482), stdev = 35540.262
  CI (99.9%): [≈ 0, 680795.722] (assumes normal distribution)


# Run complete. Total time: 00:00:22

REMEMBER: The numbers below are just data. To gain reusable insights, you need to follow up on
why the numbers are the way they are. Use profilers (see -prof, -lprof), design factorial
experiments, perform baseline and negative tests that provide experimental control, make sure
the benchmarking environment is safe on JVM/OS/HW level, ask for reviews from the domain experts.
Do not assume the numbers tell you what you want them to tell.

Benchmark              Mode  Cnt      Score        Error  Units
JsonJMHTest.bean2Map  thrpt    3  80269.397 ±  61739.014  ops/s
JsonJMHTest.map2Bean  thrpt    3  32409.045 ± 648386.677  ops/s

通過測試結(jié)果可以看出,在實現(xiàn)對象轉(zhuǎn)map時每秒可以完成8萬多次,而實現(xiàn)map轉(zhuǎn)對象轉(zhuǎn)每秒僅可完成3.2萬次。

如何優(yōu)化

我們都知道在創(chuàng)建工具類時,應(yīng)將其設(shè)計為單例模式,保證在整個系統(tǒng)中僅有一個實例,從而避免因頻繁創(chuàng)建對象而帶來的成本。

@Getter
public enum ObjectMapperInstance {
    INSTANCE;
    private final ObjectMapper objectMapper = new ObjectMapper();
    ObjectMapperInstance() {
    }
}

枚舉類型的單例實現(xiàn)天然線程安全,并且可以抵御反射攻擊。

再次測試驗證

# Fork: 1 of 1
# Warmup Iteration   1: 916836.618 ops/s
# Warmup Iteration   2: 2057459.265 ops/s
# Warmup Iteration   3: 1992614.947 ops/s
# Warmup Iteration   4: 524763.395 ops/s
# Warmup Iteration   5: 2463816.439 ops/s
Iteration   1: 2570659.849 ops/s
Iteration   2: 2557669.589 ops/s
Iteration   3: 2548610.266 ops/s


Result "org.example.JsonJMHTest.map2Bean":
  2558979.901 ±(99.9%) 202195.856 ops/s [Average]
  (min, avg, max) = (2548610.266, 2558979.901, 2570659.849), stdev = 11083.037
  CI (99.9%): [2356784.046, 2761175.757] (assumes normal distribution)


# Run complete. Total time: 00:00:30

REMEMBER: The numbers below are just data. To gain reusable insights, you need to follow up on
why the numbers are the way they are. Use profilers (see -prof, -lprof), design factorial
experiments, perform baseline and negative tests that provide experimental control, make sure
the benchmarking environment is safe on JVM/OS/HW level, ask for reviews from the domain experts.
Do not assume the numbers tell you what you want them to tell.

Benchmark              Mode  Cnt        Score          Error  Units
JsonJMHTest.bean2Map  thrpt    3  1107857.325 ± 19284117.404  ops/s
JsonJMHTest.map2Bean  thrpt    3  2558979.901 ±   202195.856  ops/s

通過將 ObjectMapper 設(shè)計為單例模式,我們可以顯著提升性能。在整個項目中只需創(chuàng)建一個 ObjectMapper 實例,避免了每次使用時重新創(chuàng)建對象所帶來的開銷。這種方法不僅提高了性能,還簡化了代碼管理和減少了內(nèi)存消耗。

同樣的原則可以應(yīng)用于其他工具類或頻繁使用的對象。例如,數(shù)據(jù)庫連接池、緩存客戶端、日志記錄器等,都可以通過單例模式來優(yōu)化性能和資源管理。確保這些組件在整個應(yīng)用生命周期內(nèi)只創(chuàng)建一次,可以最大化其效用并減少不必要的資源消耗。

總之,將頻繁使用的工具類設(shè)計為單例模式是一種良好的編程實踐,它不僅提升了性能,還增強了代碼的可維護性和可讀性。

責(zé)任編輯:武曉燕 來源: 一安未來
相關(guān)推薦

2024-07-11 08:26:00

2025-03-13 05:00:00

2024-02-26 00:00:00

Go性能工具

2023-12-29 08:29:15

QPS系統(tǒng)應(yīng)用

2023-07-14 12:28:07

JVM優(yōu)化操作

2022-04-06 08:23:57

指針函數(shù)代碼

2023-03-29 08:13:48

MySQL檢索成本

2024-02-26 00:00:00

架構(gòu)老化重構(gòu)

2021-11-04 06:58:31

CSS性能設(shè)備

2024-06-12 09:52:00

2023-08-04 08:20:56

DockerfileDocker工具

2022-05-24 08:21:16

數(shù)據(jù)安全API

2023-08-10 08:28:46

網(wǎng)絡(luò)編程通信

2023-09-10 21:42:31

2023-06-30 08:18:51

敏捷開發(fā)模式

2021-08-27 07:06:10

IOJava抽象

2024-02-20 21:34:16

循環(huán)GolangGo

2022-11-03 07:51:54

運維體系監(jiān)控

2023-12-06 08:26:19

Service數(shù)據(jù)庫

2023-07-04 08:06:40

數(shù)據(jù)庫容器公有云
點贊
收藏

51CTO技術(shù)棧公眾號