靜態初始化中不能放入繁重計算,否則會變慢!
在類初始化期間計算不可變資料結果,並將結果儲存在static final欄位中是一種非常常見的做法。實際上,這正是靜態初始化器的設計目標。
以下是在初始化時構建一些靜態表的典型示例:
public class StaticExample { static final long[] TABLE = new long[100_000_000]; static { TABLE[0] = 0; for (int i = 1; i < TABLE.length; i++) { TABLE[i] = nextValue(TABLE[i - 1]); } } private static long nextValue(long seed) { return seed * 0x123456789L + 11; } ... } |
在我的JDK 11.0.1膝上型電腦上,靜態初始化程式在大約540毫秒內填充100M元素的陣列。
現在讓我們簡單地刪除static並填充建構函式中的陣列。
public class NonStaticExample { final long[] TABLE = new long[100_000_000]; { TABLE[0] = 0; for (int i = 1; i < TABLE.length; i++) { TABLE[i] = nextValue(TABLE[i - 1]); } } private static long nextValue(long seed) { return seed * 0x123456789L + 11; } public static void main(String[] args) { new NonStaticExample(); } } |
建構函式在138毫秒內填充類似的陣列。幾乎快4倍!
為什麼靜態初始化器會變慢?這必須與JIT編譯有關,詳細分析點選標題見原文。
解決方法非常簡單:
只是不要直接在未初始化的類中進行繁重的計算。如果將計算邏輯放在沒有靜態初始化程式的輔助類中,它將不會受到效能損失的影響。
public class StaticExample { static final long[] TABLE = Helper.prepareTable(); private static class Helper { static long[] prepareTable() { long[] table = new long[100_000_000]; for (int i = 1; i < table.length; i++) { table[i] = nextValue(table[i - 1]); } return table; } static long nextValue(long seed) { return seed * 0x123456789L + 11; } } } |
相關文章
- js中函式命名不能叫write(),否則整個頁面會被重寫(空白).JS函式
- Java初始化靜態變數的時間順序Java變數
- C++類的靜態成員變數初始化C++變數
- 區域性靜態變數的初始化觀測變數
- C++ 靜態變數什麼時候完成初始化C++變數
- 理解靜態區域性變數(static)在程式中的執行規則變數
- 靜態變數變數
- 靜態路由規則配置路由
- thinkphp 偽靜態規則PHP
- 計算機網路 : 靜態路由配置計算機網路路由
- 永遠不要使用雙花括號初始化例項,否則就會OOM!OOM
- 邦芒面試:面試時這些問題不能提,否則會被降分面試
- Typecho程式偽靜態規則
- MySQL升級會變慢?MySql
- Java靜態變數在靜態方法內部無法改變值Java變數
- 【C++】靜態持續變數?如何建立靜態持續變數?C++變數
- 靜態路由介紹(雲端計算隨筆)路由
- nginx偽靜態規則重寫Nginx
- Discuz!X3.1標籤偽靜態修改和偽靜態規則
- 16 ##### 適合靜態方法的場景:方法中不使用物件的值,則直接使用靜態方法物件
- 區域性變數和全域性變數(靜態和非靜態)區別變數
- PbootCMS網站IIS偽靜態規則boot網站
- PbootCMS網站apache偽靜態規則boot網站Apache
- PbootCMS網站nginx偽靜態規則boot網站Nginx
- React:不要動,否則你會被炒魷魚React
- 千萬不要和女程式設計師做同事!否則你會愛上她程式設計師
- 如何使用 Serverless Devs 部署靜態網站到函式計算Serverdev網站函式
- static 靜態變數引起 Laravel 中佇列一個 Bug變數Laravel佇列
- 四則運算計算器
- javascript:私有變數 (靜態私有變數為什麼會被所以例項共享?-答疑解惑)JavaScript變數
- Java中靜態跟非靜態的區別總結Java
- Spring如何為靜態變數注入值Spring變數
- C++除法運算 // 靜態斷言C++
- Linux中配置靜態IPLinux
- 靜態變數在多執行緒環境下的初始化是執行緒安全的嗎?變數執行緒
- “分庫分表” ?選型和流程要慎重,否則會失控
- “分庫分表" ?選型和流程要慎重,否則會失控
- 對於systemverilog靜態變數和動態變數 ,描述不正確的是()。變數