經過@vbfool 兄指導, 將Random random = new Random(); 放至循環體外, dotnet的性能大幅提升。
以前寫企業級應用由於使用人數不多,對性能要求也不高,粗心大意慣了,沒想到一句話的位置會導致完全不同的測試結果, 慚愧慚愧!看來我真該去送外賣了~~~
說明: 測試結果 只代表在此硬件環境下,此框架下,此代碼下的一次測試結果。僅供參考!!
-------
一. 前言
作為有點經驗的碼農,現在退休在家帶孩子。閑來無事,想對使用過的框架(如果寫語言容易引戰,php是世界上最好的語言)做一個性能測試。
二. 背景
由於畢業后剛開始接觸的編程語言是C#, 從aspx時代至mvc3, mvc4, 后來又出來netcore,見證了C#的掘起和沒落(至少國內大環境不理想)。 由於大廠的示范效應加上java開源免費(現在oracle也要授權了),生態極好,所以使用spring boot開始編程,說實在的(不要噴),我個人還是比較喜歡C#,因為語法糖太好用了, lambda,匿名函數匿名類,各類型之間的比較...。 由於nodejs的發明,使js變成前后端通吃的一門語言,異步單線程,事件驅動,適用於高並發的場景。 對於接觸過的這些語言,我個人最喜歡js,因為弱類型,靈活。。。至於好或者不好,仁者見仁吧。平時一直在做碼農也沒時間去自己測試各種性能,現在正在賦閑,來測試一下我使用過的幾個框架性能,也做一下比較。
三. 框架說明
1. java現在最流行的web框架應該就是spring的全家桶套餐了,關於數據連接,我個人喜歡使用orm, 所以使用springboot + jpa
2. netcore使用自己的mvc框架,數據庫使用nhibernate, mvc+ nhibernate
3. nodej 使用egg + typeorm
四. 測試環境
1. 服務器硬件:使用我2012年從原公司100塊錢買的退役電腦當服務器,Dell OptiPlex 780,關鍵配置:CPU:Intel 酷睿2雙核 E7500, 內存:8G(自己擴的8G)
2. 服務器系統:服務器使用centos 7.7
初始使用為
3. 數據庫: mysql 8.5(放在我的測試機個人筆記本上,避免mysql影響其他框架
4. 測試機(局域網內,TP-link百兆路由器連接, 本人筆記本)配置:
5. 各框架版本:
1) java : 1.8 , spring boot 2.1.4, jpa 2.1.6
2) netcore: 3.1, nhibernate:5.2.7
3) nodejs:v12.16.3, egg:2.15.1 typeorm:0.2.24
五. 測試工具
jmeter 5.1.1
六. 測試計划
准備一張測試表
CREATE TABLE `db_test` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`string_field` varchar(200) DEFAULT NULL,
`int_field` int(11) DEFAULT NULL,
`float_field` float DEFAULT NULL,
`create_time` timestamp NULL DEFAULT NULL,
`medium_string_field` mediumtext,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=585887 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1. 單項測試:
1.1. 新增一條隨機數據,由於帶寬的原因,不返回。, jmeter 線程數200 循環500次(10萬次)
1.2. 按id倒序 查詢第1條數據,由於帶寬的原因,不返回。 jmeter 線程數200 循環500次(10萬次)
1.3. 新增一條隨機數據,再刪除掉, 由於帶寬的原因,不返回。jmeter 線程數200 循環500次(10萬次)
1.4. 隨機創建1W個數字至數組,由於帶寬的原因,不返回。利用自身的排序進行正序排序, jmeter 線程數200 循環500次(10萬次)
1.5. 隨機創建5W個數字至數組,由於帶寬的原因,不返回。利用自身的排序進行正序排序, jmeter 線程數200 循環500次(10萬次)
1.6. 隨機創建10W個數字至數組,由於帶寬的原因,不返回。利用自身的排序進行正序排序, jmeter 線程數200 循環500次(10萬次)
1.7. 請求約0.1M的文件,jmeter 線程數200 循環500次(10萬次, 由於網卡和路由器的原因,不能在服務器上進行測試)
1.8. 請求約1M的文件,jmeter 線程數200 循環500次(10萬次, 由於網卡和路由器的原因,不能在服務器上進行測試)
2. 綜合測試:將以上測試項(1.1- 1.6) 放在一起,分別測試並發200(200x1), 600(200x3), 1000(200x5), 5000(200x25), 10000(200x50)
3. 用nodejs 寫一個采集服務器數據的程序,每1秒采集一次服務器的CPU和內存的使用情況(通過centos的 top -b n 2 指令)插入至mysql數據庫。表也放在測試機上。
CREATE TABLE `env_info` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(100) DEFAULT NULL COMMENT '名稱',
`cpu` decimal(10,3) DEFAULT NULL COMMENT 'CPU占有率',
`mem_private` bigint(20) DEFAULT NULL,
`mem_virtual` bigint(20) DEFAULT NULL,
`mem_usage` decimal(10,3) DEFAULT NULL,
`create_time` timestamp NULL DEFAULT NULL COMMENT '創建時間',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=51119 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
七. 測試指標
1. jmeter聚合報告
2. 資源占用(均為最高占用, 不是平均值)
八. 測試代碼
如果需要,可以給我發文件索取:lei_xu@163.com
九. 測試結果
1. jmeter聚合報告
2. 資源占用(均為最高占用, 不是平均值)
十. 結論
1. 從資源占用來看CPU都占滿了, 但內存使用情況: dotnet> java > nodejs。
2. 單表數據庫操作,
2.1. 吞吐量 nodejs > java > dotnet , nodejs 的吞吐量幾乎是java的2倍;
2.2. 平均值和中位數: nodejs > java > dotnet , nodej 幾乎是java的1/2,說明nodejs的響應時間最少
2.3. 標准偏差: java > nodejs > dotnet, java 相對其他框架更平穩。
2.4. 異常率:nodejs 在查詢時出現了異常,未查原因
綜上, nodejs 在小數據轉發上具有先天優勢,低消耗,轉發能力最強,但是java更平穩。
3. 密集運算(排序)
3.1. 吞吐量 java> nodejs > dotnet, 但隨着數據量增多,nodejs和java的吞吐量越來越相近(?)
3.2. 平均值和中位數: java> nodejs> dotnet, 但隨着數據量增多, nodejs和java的平均值和中位數越來越相近(?)
3.3. 標准偏差:nodejs > java> dotnet , nodejs 標准偏差與其他兩個不是一個量級,說明nodejs慢的比較平穩
3.4. 異常率:sort1W時,java出現了異常,未查原因
綜上, 密集運算java相對比較強勢, nodejs表現中規中矩,相對更平穩。
3.1. 吞吐量 dotnet > java> nodejs , 但隨着數據量增多,nodejs和java的吞吐量越來越相近(?) . dotnet 吞吐量可以達到java的3-4倍
3.2. 平均值和中位數: dotnet> java> nodejs> , 但隨着數據量增多, nodejs和java的平均值和中位數越來越相近(?). dotnet 平均值和中位數與吞吐量表現一致,是java的1/3 - 1/4
3.3. 標准偏差:nodejs > dotnet > java , nodejs 標准偏差最低,說明nodejs慢的比較平穩. dotnet 僅隨其后。
3.4. 異常率:sort1W時,java出現了異常,未查原因
綜上,dotnet的簡單密集運算表現最好, 即高效又平穩,且大幅領先其他框架。
4. 綜合並發
4.1. 吞吐量 dotnet>java> nodejs , java幾乎是nodejs的兩倍. dotnet在並發600及1000時表現有點奇怪(?)其他情況都是小幅領先。
4.2. 平均值和中位數: java> dotnet> nodejs, java幾乎是nodejs的1/2。 dotnet 緊隨其后
4.3. 標准偏差:java > nodejs> dotnet , java更平穩, 但隨着並發數增高,java,nodejs,dotnet相差不大,nodejs相對也平穩, 都相對平穩
4.4. 異常率:未出現異常。
綜上, 綜合並發上dotnet表現相對要好,吞吐量小幅領先,運行也相對平穩。
綜合以上簡單的測試,
java springboot資源占用率最高(可能是設置的), 綜合吞吐量相對較高,運行相對平穩。綜合表現很好.
nodejs egg資源占用率最低, 轉發小規模數據表現亮眼,符合nodejs本身的特性,由於密集運算的拖累,綜合表現不及java, 所以nodejs可以運用在數據轉發方面。
dotnet mvc太令我失望了(可能是框架搭的不好)
dotnet mvc除了簡單操作數據庫效率比較低以外(NHibernate 本身效率低),其他表現非常好,綜合表現也很好。微軟在dotnetcore上下了大功夫,除了跨平台, 其他也確實改善很多。
原創,轉載請聯系:lei_xu@163.com