最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java理論基礎Stream性能論證測試示例

 更新時間:2022年03月16日 11:57:31   作者:字母哥哥  
這篇文章主要為大家介紹了java理論基礎Stream性能論證的測試示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步

一、粉絲的反饋

問:stream比for循環(huán)慢5倍,用這個是為了啥? 答:互聯(lián)網是一個新聞泛濫的時代,三人成虎,以假亂真的事情時候發(fā)生。作為一個技術開發(fā)者,要自己去動手去做,不要人云亦云。

的確,這位粉絲說的這篇文章我也看過,我就不貼地址了,也沒必要給他帶流量。怎么說呢?就是一個不懂得測試的、不入流開發(fā)工程師做的性能測試,給出了一個危言聳聽的結論。

二、所有性能測試結論都是片面的

性能測試是必要的,但針對性能測試的結果,永遠要持懷疑態(tài)度。為什么這么說?

  • 性能測試脫離業(yè)務場景就是片面的性能測試。你能覆蓋所有的業(yè)務場景么?
  • 性能測試脫離硬件環(huán)境就是片面的性能測試。你能覆蓋所有的硬件環(huán)境么?
  • 性能測試脫離開發(fā)人員的知識面就是片面的性能測試。你能覆蓋各種開發(fā)人員奇奇怪怪的代碼么?

所以,我從來不相信網上的任何性能測試的文章。凡是我自己的從事的業(yè)務場景,我都要在接近生產環(huán)境的機器上自己測試一遍。 所有性能測試結論都是片面的,只有你生產環(huán)境下的運行結果才是真的。

三、動手測試Stream的性能

3.1.環(huán)境

windows10 、16G內存、i7-7700HQ 2.8HZ 、64位操作系統(tǒng)、JDK 1.8.0_171

3.2.測試用例與測試結論

我們在上一節(jié),已經講過:

  • 針對不同的數(shù)據(jù)結構,Stream流的執(zhí)行效率是不一樣的
  • 針對不同的數(shù)據(jù)源,Stream流的執(zhí)行效率也是不一樣的

所以記住筆者的話:所有性能測試結論都是片面的,你要自己動手做,相信你自己的代碼和你的環(huán)境下的測試!我的測試結果僅僅代表我自己的測試用例和測試數(shù)據(jù)結構!

3.2.1.測試用例一

測試用例:5億個int隨機數(shù),求最小值 測試結論(測試代碼見后文):

  • 使用普通for循環(huán),執(zhí)行效率是Stream串行流的2倍。也就是說普通for循環(huán)性能更好。
  • Stream并行流計算是普通for循環(huán)執(zhí)行效率的4-5倍。
  • Stream并行流計算 > 普通for循環(huán) > Stream串行流計算

3.2.2測試用例二

測試用例:長度為10的1000000隨機字符串,求最小值 測試結論(測試代碼見后文):

  • 普通for循環(huán)執(zhí)行效率與Stream串行流不相上下
  • Stream并行流的執(zhí)行效率遠高于普通for循環(huán)
  • Stream并行流計算 > 普通for循環(huán) = Stream串行流計算

3.2.3測試用例三

測試用例:10個用戶,每人200個訂單。按用戶統(tǒng)計訂單的總價。 測試結論(測試代碼見后文):

  • Stream并行流的執(zhí)行效率遠高于普通for循環(huán)
  • Stream串行流的執(zhí)行效率大于等于普通for循環(huán)
  • Stream并行流計算 > Stream串行流計算 >= 普通for循環(huán)

四、最終測試結論

對于簡單的數(shù)字(list-Int)遍歷,普通for循環(huán)效率的確比Stream串行流執(zhí)行效率高(1.5-2.5倍)。但是Stream流可以利用并行執(zhí)行的方式發(fā)揮CPU的多核優(yōu)勢,因此并行流計算執(zhí)行效率高于for循環(huán)。

對于list-Object類型的數(shù)據(jù)遍歷,普通for循環(huán)和Stream串行流比也沒有任何優(yōu)勢可言,更不用提Stream并行流計算。

雖然在不同的場景、不同的數(shù)據(jù)結構、不同的硬件環(huán)境下。Stream流與for循環(huán)性能測試結果差異較大,甚至發(fā)生逆轉。但是總體上而言:

  • Stream并行流計算 >> 普通for循環(huán) ~= Stream串行流計算 (之所以用兩個大于號,你細品)
  • 數(shù)據(jù)容量越大,Stream流的執(zhí)行效率越高。
  • Stream并行流計算通常能夠比較好的利用CPU的多核優(yōu)勢。CPU核心越多,Stream并行流計算效率越高。

stream比for循環(huán)慢5倍?也許吧,單核CPU、串行Stream的int類型數(shù)據(jù)遍歷?我沒試過這種場景,但是我知道這不是應用系統(tǒng)的核心場景。看了十幾篇測試博文,和我的測試結果。我的結論是: 在大多數(shù)的核心業(yè)務場景下及常用數(shù)據(jù)結構下,Stream的執(zhí)行效率比for循環(huán)更高。 畢竟我們的業(yè)務中通常是實實在在的實體對象,沒事誰總對List<Int>類型進行遍歷?誰的生產服務器是單核?。

五、測試代碼

<dependency>
    <groupId>com.github.houbb</groupId>
    <artifactId>junitperf</artifactId>
    <version>2.0.0</version>
</dependency>

測試用例一:

import com.github.houbb.junitperf.core.annotation.JunitPerfConfig;
import com.github.houbb.junitperf.core.report.impl.HtmlReporter;
import org.junit.jupiter.api.BeforeAll;
import java.util.Arrays;
import java.util.Random;
public class StreamIntTest {
    public static int[] arr;
    @BeforeAll
    public static void init() {
        arr = new int[500000000];  //5億個隨機Int
        randomInt(arr);
    }
    @JunitPerfConfig( warmUp = 1000, reporter = {HtmlReporter.class})
    public void testIntFor() {
        minIntFor(arr);
    }
    @JunitPerfConfig( warmUp = 1000, reporter = {HtmlReporter.class})
    public void testIntParallelStream() {
        minIntParallelStream(arr);
    }
    @JunitPerfConfig( warmUp = 1000, reporter = {HtmlReporter.class})
    public void testIntStream() {
        minIntStream(arr);
    }
    private int minIntStream(int[] arr) {
        return Arrays.stream(arr).min().getAsInt();
    }
    private int minIntParallelStream(int[] arr) {
        return Arrays.stream(arr).parallel().min().getAsInt();
    }
    private int minIntFor(int[] arr) {
        int min = Integer.MAX_VALUE;
        for (int anArr : arr) {
            if (anArr < min) {
                min = anArr;
            }
        }
        return min;
    }
    private static void randomInt(int[] arr) {
        Random r = new Random();
        for (int i = 0; i < arr.length; i++) {
            arr[i] = r.nextInt();
        }
    }
}

測試用例二:

import com.github.houbb.junitperf.core.annotation.JunitPerfConfig;
import com.github.houbb.junitperf.core.report.impl.HtmlReporter;
import org.junit.jupiter.api.BeforeAll;
import java.util.ArrayList;
import java.util.Random;
public class StreamStringTest {
    public static ArrayList<String> list;
    @BeforeAll
    public static void init() {
        list = randomStringList(1000000);
    }
    @JunitPerfConfig(duration = 10000, warmUp = 1000, reporter = {HtmlReporter.class})
    public void testMinStringForLoop(){
        String minStr = null;
        boolean first = true;
        for(String str : list){
            if(first){
                first = false;
                minStr = str;
            }
            if(minStr.compareTo(str)>0){
                minStr = str;
            }
        }
    }
    @JunitPerfConfig(duration = 10000, warmUp = 1000, reporter = {HtmlReporter.class})
    public void textMinStringStream(){
        list.stream().min(String::compareTo).get();
    }
    @JunitPerfConfig(duration = 10000, warmUp = 1000, reporter = {HtmlReporter.class})
    public void testMinStringParallelStream(){
        list.stream().parallel().min(String::compareTo).get();
    }
    private static ArrayList<String> randomStringList(int listLength){
        ArrayList<String> list = new ArrayList<>(listLength);
        Random rand = new Random();
        int strLength = 10;
        StringBuilder buf = new StringBuilder(strLength);
        for(int i=0; i<listLength; i++){
            buf.delete(0, buf.length());
            for(int j=0; j<strLength; j++){
                buf.append((char)('a'+ rand.nextInt(26)));
            }
            list.add(buf.toString());
        }
        return list;
    }
}

測試用例三:

import com.github.houbb.junitperf.core.annotation.JunitPerfConfig;
import com.github.houbb.junitperf.core.report.impl.HtmlReporter;
import org.junit.jupiter.api.BeforeAll;
import java.util.*;
import java.util.stream.Collectors;
public class StreamObjectTest {
    public static List<Order> orders;
    @BeforeAll
    public static void init() {
        orders = Order.genOrders(10);
    }
    @JunitPerfConfig(duration = 10000, warmUp = 1000, reporter = {HtmlReporter.class})
    public void testSumOrderForLoop(){
        Map<String, Double> map = new HashMap<>();
        for(Order od : orders){
            String userName = od.getUserName();
            Double v; 
            if((v=map.get(userName)) != null){
                map.put(userName, v+od.getPrice());
            }else{
                map.put(userName, od.getPrice());
            }
        }
    }
    @JunitPerfConfig(duration = 10000, warmUp = 1000, reporter = {HtmlReporter.class})
    public void testSumOrderStream(){
        orders.stream().collect(
                Collectors.groupingBy(Order::getUserName, 
                        Collectors.summingDouble(Order::getPrice)));
    }
    @JunitPerfConfig(duration = 10000, warmUp = 1000, reporter = {HtmlReporter.class})
    public void testSumOrderParallelStream(){
        orders.parallelStream().collect(
                Collectors.groupingBy(Order::getUserName, 
                        Collectors.summingDouble(Order::getPrice)));
    }
}
class Order{
    private String userName;
    private double price;
    private long timestamp;
    public Order(String userName, double price, long timestamp) {
        this.userName = userName;
        this.price = price;
        this.timestamp = timestamp;
    }
    public String getUserName() {
        return userName;
    }
    public double getPrice() {
        return price;
    }
    public long getTimestamp() {
        return timestamp;
    }
    public static List<Order> genOrders(int listLength){
        ArrayList<Order> list = new ArrayList<>(listLength);
        Random rand = new Random();
        int users = listLength/200;// 200 orders per user
        users = users==0 ? listLength : users;
        ArrayList<String> userNames = new ArrayList<>(users);
        for(int i=0; i<users; i++){
            userNames.add(UUID.randomUUID().toString());
        }
        for(int i=0; i<listLength; i++){
            double price = rand.nextInt(1000);
            String userName = userNames.get(rand.nextInt(users));
            list.add(new Order(userName, price, System.nanoTime()));
        }
        return list;
    }
    @Override
    public String toString(){
        return userName + "::" + price;
    }
}

以上就是java理論基礎Stream性能論證測試示例的詳細內容,更多關于java Stream性能測試的資料請關注腳本之家其它相關文章!

相關文章

  • 解決Maven本地倉庫明明有對應的jar包但還是報找不到的問題

    解決Maven本地倉庫明明有對應的jar包但還是報找不到的問題

    這篇文章主要介紹了解決Maven本地倉庫明明有對應的jar包但還是報找不到的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • 淺談Java中GuavaCache返回Null的注意事項

    淺談Java中GuavaCache返回Null的注意事項

    Guava在實際的Java后端項目中應用的場景還是比較多的,比如限流,緩存,容器操作之類的,本文主要介紹了GuavaCache返回Null的注意事項,感興趣的可以了解一下
    2021-10-10
  • 解決BeanUtils.copyProperties不支持復制集合的問題

    解決BeanUtils.copyProperties不支持復制集合的問題

    這篇文章主要介紹了解決BeanUtils.copyProperties不支持復制集合的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • Java使用Jasypt進行加密和解密的技術指南

    Java使用Jasypt進行加密和解密的技術指南

    Jasypt (Java Simplified Encryption) 是一個簡化 Java 應用中加密工作的庫,它支持加密和解密操作,易于與 Spring Boot 集成,通過 Jasypt,可以安全地管理敏感信息,比如數(shù)據(jù)庫密碼、API 密鑰等,本文介紹了Java使用Jasypt進行加密和解密的技術指南,需要的朋友可以參考下
    2025-03-03
  • Java項目中如何訪問WEB-INF下jsp頁面

    Java項目中如何訪問WEB-INF下jsp頁面

    這篇文章主要介紹了Java項目中如何訪問WEB-INF下jsp頁面,文章通過示例代碼和圖文解析介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-08-08
  • mybatis-plus?實現(xiàn)查詢表名動態(tài)修改的示例代碼

    mybatis-plus?實現(xiàn)查詢表名動態(tài)修改的示例代碼

    通過MyBatis-Plus實現(xiàn)表名的動態(tài)替換,根據(jù)配置或入?yún)⑦x擇不同的表,本文主要介紹了mybatis-plus?實現(xiàn)查詢表名動態(tài)修改的示例代碼,具有一定的參考價值,感興趣的可以了解一下
    2025-03-03
  • SpringBoot3讀取配置文件application.properties屬性值的幾種方式

    SpringBoot3讀取配置文件application.properties屬性值的幾種方式

    這篇文章主要介紹了SpringBoot3讀取配置文件application.properties屬性值的幾種方式,文中通過代碼示例給大家講解的非常詳細,對大家的學習或工作有一定的幫助,需要的朋友可以參考下
    2024-11-11
  • sharding-jdbc讀寫分離原理詳細解析

    sharding-jdbc讀寫分離原理詳細解析

    這篇文章主要介紹了sharding-jdbc讀寫分離原理詳細解析,很多時候,為了應付DB的高并發(fā)讀寫,我們會采用讀寫分離技術,讀寫分離指的是利用數(shù)據(jù)庫主從技術(把數(shù)據(jù)復制到多個節(jié)點中),分散讀多個庫以支持高并發(fā)的讀,需要的朋友可以參考下
    2023-12-12
  • 攔截JSP頁面,校驗是否已登錄詳解及實現(xiàn)代碼

    攔截JSP頁面,校驗是否已登錄詳解及實現(xiàn)代碼

    這篇文章主要介紹了攔截JSP頁面,校驗是否已登錄詳解及實現(xiàn)代碼的相關資料,需要的朋友可以參考下
    2016-11-11
  • SpringBoot如何配置tomcat access日志

    SpringBoot如何配置tomcat access日志

    access日志記錄了每一個HTTP請求的信息,包括請求的來源、請求的資源、響應狀態(tài)碼等,常常用來做數(shù)據(jù)統(tǒng)計、性能監(jiān)控,比如通過分析訪問日志,可以發(fā)現(xiàn)性能瓶頸和優(yōu)化機會,提升應用的響應速度等,這篇文章主要介紹了SpringBoot配置tomcat access日志,需要的朋友可以參考下
    2024-05-05

最新評論

石屏县| 张北县| 南城县| 收藏| 刚察县| 平江县| 庐江县| 金沙县| 象州县| 临高县| 乌兰察布市| 丹寨县| 会昌县| 沾化县| 台州市| 吴川市| 固原市| 九龙坡区| 磴口县| 冕宁县| 沭阳县| 顺昌县| 扎鲁特旗| 白水县| 滦平县| 明水县| 顺平县| 信丰县| 嘉祥县| 崇信县| 梧州市| 克拉玛依市| 乳山市| 库车县| 永寿县| 临武县| 义马市| 新竹县| 怀柔区| 德钦县| 义乌市|