成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

我們一起聊聊對象與 Map 轉換性能優化方案

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

前言

有粉絲提到每次都需要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) 對這段代碼進行基準測試,以便大家對其性能有一個直觀的了解。

圖片圖片

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

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

依賴引入

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

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

注解說明

BenchmarkMode

名稱

解釋

單位

Mode.Throughput

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

ops/time

Mode.AverageTime

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

time/op

Mode.SampleTime

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

time

Mode.SingleShotTime

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


All

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


OutputTimeUnit

統計的時間單位

Warmup、Measurement

名稱

解釋

iterations

預熱次數

time

預熱時間

timeUnit

預熱時間單位

batchSize

同時預熱

State

名稱

解釋

Benchmark

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

Group

每一組中共享線程

Thread

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

Fork

進行次數,如果 fork 數是2的話,則 JMH 會 fork 出兩個進程來進行測試

Benchmark

表示該方法是需要進行 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();
    }

測試結果:

# 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

通過測試結果可以看出,在實現對象轉map時每秒可以完成8萬多次,而實現map轉對象轉每秒僅可完成3.2萬次。

如何優化

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

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

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

再次測試驗證

# 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 設計為單例模式,我們可以顯著提升性能。在整個項目中只需創建一個 ObjectMapper 實例,避免了每次使用時重新創建對象所帶來的開銷。這種方法不僅提高了性能,還簡化了代碼管理和減少了內存消耗。

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

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

責任編輯:武曉燕 來源: 一安未來
相關推薦

2024-07-11 08:26:00

2025-03-13 05:00:00

2025-06-11 02:10:00

2024-02-26 00:00:00

Go性能工具

2023-12-29 08:29:15

QPS系統應用

2022-04-06 08:23:57

指針函數代碼

2023-07-14 12:28:07

JVM優化操作

2024-02-26 00:00:00

架構老化重構

2021-11-04 06:58:31

CSS性能設備

2023-03-29 08:13:48

MySQL檢索成本

2024-06-12 09:52:00

2024-02-20 21:34:16

循環GolangGo

2021-08-27 07:06:10

IOJava抽象

2023-08-10 08:28:46

網絡編程通信

2023-08-04 08:20:56

DockerfileDocker工具

2023-06-30 08:18:51

敏捷開發模式

2022-05-24 08:21:16

數據安全API

2023-09-10 21:42:31

2024-01-29 09:01:20

React列表模式

2023-07-04 08:06:40

數據庫容器公有云
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美一区免费在线观看 | 中文字幕一二三区 | 狠狠做深爱婷婷综合一区 | 亚洲精品亚洲人成人网 | 国产一区二区三区免费 | 99国产精品一区二区三区 | 中文字幕国产视频 | 黄色一级在线播放 | 国产精品久久久久久久久久久久 | 精品1区2区| 国产成人av一区二区三区 | 日韩中文字幕在线视频观看 | 天天综合国产 | 日韩字幕一区 | 久久高清国产视频 | 91久久精品一区二区二区 | 精品久久成人 | 人人干人人舔 | 性天堂网 | 国产成人一区二区三区电影 | 久在线视频 | 精品免费国产视频 | 精品久久久久国产免费第一页 | 激情欧美日韩一区二区 | 粉嫩一区二区三区国产精品 | 韩国av网站在线观看 | 成人免费三级电影 | 亚洲精品在 | 亚洲精品久久久久久久久久久久久 | 欧美一区二区三区视频在线 | 欧美三级视频 | 欧美一区二区三区在线观看 | 国产一区二区三区四区区 | 一级毛毛片| 9久久婷婷国产综合精品性色 | 日本天天色| 天天草天天爱 | 精品无码久久久久国产 | 综合色站导航 | 亚洲一区二区电影网 | 国产亚洲精品综合一区 |