靜態初始化中不能放入繁重計算,否則會變慢!
在類初始化期間計算不可變資料結果,並將結果儲存在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函式
- js中的靜態變數JS變數
- 靜態變數和非靜態變數變數
- Java初始化靜態變數的時間順序Java變數
- C++類的靜態成員變數初始化C++變數
- 區域性靜態變數的初始化觀測變數
- 靜態變數與靜態方法變數
- 邦芒面試:面試時這些問題不能提,否則會被降分面試
- C++ 靜態變數什麼時候完成初始化C++變數
- 理解靜態區域性變數(static)在程式中的執行規則變數
- 靜態變數變數
- 永遠不要使用雙花括號初始化例項,否則就會OOM!OOM
- 遞迴程式中的靜態變數遞迴變數
- 計算機網路 : 靜態路由配置計算機網路路由
- thinkphp 偽靜態規則PHP
- 靜態路由規則配置路由
- 獲取和放入原則
- MySQL升級會變慢?MySql
- 靜態路由介紹(雲端計算隨筆)路由
- java優化程式設計-靜態變數Java優化程式設計變數
- 靜態初始化--我的理解 (轉)
- 繫結變數在靜態sql和動態sql中變數SQL
- 深入理解Java中靜態初始化塊、初始化塊和構造方法Java構造方法
- Typecho程式偽靜態規則
- 【C++】靜態持續變數?如何建立靜態持續變數?C++變數
- Java靜態變數在靜態方法內部無法改變值Java變數
- java中靜態初始化塊,例項初始化塊,建構函式區別Java函式
- 靜態持續變數變數
- 靜態變數和Session變數Session
- C++ 變數初始化規則C++變數
- React:不要動,否則你會被炒魷魚React
- Nginx常用Rewrite偽靜態規則Nginx
- PHP類的靜態(static)方法和靜態(static)變數PHP變數
- 16 ##### 適合靜態方法的場景:方法中不使用物件的值,則直接使用靜態方法物件
- 區域性變數和全域性變數(靜態和非靜態)區別變數
- static靜態變數的理解變數
- 千萬不要和女程式設計師做同事!否則你會愛上她程式設計師
- PbootCMS網站IIS偽靜態規則boot網站