• <noscript id="ecgc0"><kbd id="ecgc0"></kbd></noscript>
    <menu id="ecgc0"></menu>
  • <tt id="ecgc0"></tt>

    JavaScript數組的進化

    JavaScript 數組不是連續(contiguous)的,其實現類似哈希映射(hash-maps)或字典(dictionaries)。覺得這有點像是一門 B 級語言,數組實現根本不恰當。

    工具/原料

    • JavaScript、電腦操作系統

    方法/步驟

    1. 1

      為什么說 JavaScript 數組不是真正的數組

      數組是一串連續的內存位置,用來保存某些值。注意重點,“連續”(continuous,或 contiguous),這很重要。

    2. 2

      上圖展示了數組在內存中存儲方式。這個數組保存了 4 個元素,每個元素 4 字節。加起來總共占用了 16 字節的內存區。

      假設聲明了 tinyInt arr[4];,分配到的內存區的地址從 1201 開始。一旦需要讀取 arr[2],只需要通過數學計算拿到 arr[2] 的地址即可。計算 1201 + (2 X 4),直接從 1209 開始讀取即可。

    3. 3

      JavaScript 中的數據是哈希映射,可以使用不同的數據結構來實現,如鏈表。所以,如果在 JavaScript 中聲明一個數組 var arr = new Array(4),計算機將生成類似上圖的結構。如果程序需要讀取 arr[2],則需要從 1201 開始遍歷尋址。

      以上急速 JavaScript 數組與真實數組的不同之處。顯而易見,數學計算比遍歷鏈表快。就長數組而言,情況尤其如此。

      JavaScript 數組的進化

      JavaScript 這門語言也進化了不少。從 V8、SpiderMonkey 到 TC39 和與日俱增的 Web 用戶,巨大的努力已經使 JavaScript 成為世界級必需品。一旦有了龐大的用戶基礎,性能提升自然是硬需求。

      現代 JavaScript 引擎是會給數組分配連續內存的 —— 如果數組是同質的(所有元素類型相同)。優秀的程序員總會保證數組同質,以便 JIT(即時編譯器)能夠使用 c 編譯器式的計算方法讀取元素。

      想要在某個同質數組中插入一個其他類型的元素,JIT 將解構整個數組,并按照舊有的方式重新創建。

      如果代碼寫得不太糟,JavaScript Array 對象在幕后依然保持著真正的數組形式,這對現代 JS 開發者來說極為重要。

      數組跟隨 ES2015/ES6 有了更多的演進。TC39 決定引入類型化數組(Typed Arrays),于是我們就有了 ArrayBuffer。

      ArrayBuffer 提供一塊連續內存供隨意操作。直接操作內存還是太復雜、偏底層。于是便有了處理 ArrayBuffer 的視圖(View)。目前已有一些可用視圖,未來還會有更多加入。

    4. 4

      了解更多關于類型化數組(Typed Arrays)的知識,請訪問 MDN 文檔。

      高性能、高效率的類型化數組在 WebGL 之后被引入。WebGL 工作者遇到了極大的性能問題,即如何高效處理二進制數據。可以使用 SharedArrayBuffer 在多個 Web Worker 進程之間共享數據提升性能。

      從簡單的哈希映射到現在的 SharedArrayBuffer

      舊式數組 vs 類型化數組:性能

      前面已經討論了 JavaScript 數組的演進,現在來測試現代數組到底能帶來多大收益。

    5. 5

      舊式數組和 ArrayBuffer 的性能不相上下,現代編譯器已經智能化,能夠將元素類型相同的傳統數組在內部轉換成內存連續的數組。第一個例子正是如此。盡管使用了 new Array(LIMIT),數組實際依然以現代數組形式存在。

      接著修改第一例子,將數組改成異構型(元素類型不完全一致)的,來看看是否存在性能差異。

    6. 6

      改變發生在第 3 行,添加一條語句,將數組變為異構類型。其余代碼保持不變。性能差異表現出來了,慢了 22 倍。

      舊式數組:讀取

    7. 7

      類型化數組的引入是 JavaScript 發展歷程中的一大步。Int8Array,Uint8Array,Uint8ClampedArray,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array,這些是類型化數組視圖,使用原生字節序(與本機相同)。我們還可以使用 DataView 創建自定義視圖窗口。希望未來會有更多幫助我們輕松操作 ArrayBuffer 的 DataView 庫。

      JavaScript 數組的演進非常 nice。現在它們速度快、效率高、健壯,在內存分配時也足夠智能。

    • 發表于 2018-02-10 00:00
    • 閱讀 ( 751 )
    • 分類:其他類型

    你可能感興趣的文章

    相關問題

    0 條評論

    請先 登錄 后評論
    admin
    admin

    0 篇文章

    作家榜 ?

    1. xiaonan123 189 文章
    2. 湯依妹兒 97 文章
    3. luogf229 46 文章
    4. jy02406749 45 文章
    5. 小凡 34 文章
    6. Daisy萌 32 文章
    7. 我的QQ3117863681 24 文章
    8. 華志健 23 文章

    聯系我們:uytrv@hotmail.com 問答工具
  • <noscript id="ecgc0"><kbd id="ecgc0"></kbd></noscript>
    <menu id="ecgc0"></menu>
  • <tt id="ecgc0"></tt>
    久久久久精品国产麻豆