Scala ArrayBuffer/ListBuffer vs Java ArrayList

在我們編寫Scala代碼的時候,由于ListBuffer方便的特性,所以經(jīng)常會使用ListBuffer鼠冕。過去也一直沒有什么問題。

但是呢防症,最近在我們的項目中,出現(xiàn)了一個非常嚴重的性能問題。通過JProfiler分析告希,發(fā)現(xiàn)是調(diào)用ListBuffer的獲取數(shù)據(jù)的方法時扑浸,太慢導(dǎo)致的。

差距有多大呢燕偶?以前需要運行12個小時,改成了Java的List以后酝惧,直接縮短了四個小時伯诬。

這篇文章中,我不會具體分析ArrayBuffer/ScalaBuffer等的代碼哩陕,只會給出測試的結(jié)果赫舒。

Scala ArrayBuffer

package com.hyper

import scala.collection.JavaConverters._
import scala.collection.mutable.ArrayBuffer

object TestScalaList {

    def main(args: Array[String]): Unit = {

        val scalaListBuffer: ArrayBuffer[String] = ArrayBuffer[String]()
        val itemNumber = 100000

        for (i <- 0 until itemNumber) {
            scalaListBuffer += i.toString
        }

        IterateList.iterate(scalaListBuffer.toList.asJava)
    }

}

IterateList的代碼如下:

package com.hyper;

import com.google.common.base.Stopwatch;

import java.util.List;
import java.util.concurrent.TimeUnit;

public class IterateList {

    public static void iterate(List<String> list) {
        int listLength = list.size();

        System.out.println("List length: " + listLength);

        Stopwatch stopwatch = new Stopwatch();
        stopwatch.start();

        System.out.println("List class: " + list.getClass());
        for (int i = 0; i < listLength; i++) {
            list.get(i);
        }

        long elapse = stopwatch.elapsed(TimeUnit.SECONDS);
        System.out.println("elapse: " + elapse);
    }

}

運行上面的代碼心赶,我們可以看到如下結(jié)果:


運行了15s缨叫。時間不短荔燎。它的底層還是數(shù)組實現(xiàn)的呢。

Java ArrayList

那我們再來看下Java ArrayList的性能咏闪。

package com.hyper;

import java.util.ArrayList;
import java.util.List;

public class TestJavaList {

    public static void main(String[] args) {
        List<String> list = new ArrayList<>();

        int itemNumber = 100000;

        for (int i = 0; i < itemNumber; i++) {
            list.add(String.valueOf(i));
        }

        IterateList.iterate(list);
    }

}

結(jié)果如下:


僅僅用了0s,1s都不到纵装。

都是用數(shù)組實現(xiàn)的,差距咋這么大呢诗箍?

我沒有仔細探究挽唉,猜測一個是因為SeqWrapper這東西筷狼,增加了調(diào)用棧的深度埂材,進一步增加了運行時間汤求,但是這個應(yīng)該不會導(dǎo)致這么大的差距。所以更可能的原因是扬绪,Scala實現(xiàn)的這個ArrayBuffer就有問題。

有時間仔細研究一下源碼和字節(jié)碼挤牛,補充上來。

Scala ListBuffer

這個是我們Scala中最常用的數(shù)據(jù)結(jié)構(gòu)格二,Spark代碼中也有意無意的總用到這個數(shù)據(jù)結(jié)構(gòu)竣蹦。

我們都知道,Java中ArrayList和LinkedList這兩種數(shù)據(jù)結(jié)構(gòu)长窄,各有各的優(yōu)缺點纲菌,各有各的應(yīng)用場景。在Scala中嚣潜,ArrayBuffer就是ArrayList的另一個版本椅贱,而ListBuffer就是LinkedList的另一個版本。所以计技,拿ListBuffer那兩個數(shù)據(jù)結(jié)構(gòu)對比山橄,有點不公平。畢竟ListBuffer不適合隨機讀取睡雇。

但是既然做了,這里還是貼上來秕豫。

package com.hyper

import scala.collection.JavaConverters._
import scala.collection.mutable.ListBuffer

object TestScalaList {

    def main(args: Array[String]): Unit = {

        val scalaListBuffer: ListBuffer[String] = ListBuffer[String]()
        val itemNumber = 100000

        for (i <- 0 until itemNumber) {
            scalaListBuffer += i.toString
        }

        IterateList.iterate(scalaListBuffer.toList.asJava)
    }

}

結(jié)果如下:


Oh My God馁蒂,竟然運行了45s蜘腌。

總結(jié)

從測試結(jié)果中,我們可以看到沮脖,Scala代碼芯急,性能跟Java代碼還是有一定差距的。

所以能用Java還是盡量用Java為好免姿。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末榕酒,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子紊婉,更是在濱河造成了極大的恐慌辑舷,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,682評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件肢础,死亡現(xiàn)場離奇詭異乔妈,居然都是意外死亡氓皱,警方通過查閱死者的電腦和手機波材,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來唯灵,“玉大人隙轻,你說我怎么就攤上這事×泊桑” “怎么了斑匪?”我有些...
    開封第一講書人閱讀 165,083評論 0 355
  • 文/不壞的土叔 我叫張陵蚀瘸,是天一觀的道長。 經(jīng)常有香客問我贮勃,道長,這世上最難降的妖魔是什么奏瞬? 我笑而不...
    開封第一講書人閱讀 58,763評論 1 295
  • 正文 為了忘掉前任丝格,我火速辦了婚禮棵譬,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘曼尊。我一直安慰自己,他們只是感情好骆撇,可當我...
    茶點故事閱讀 67,785評論 6 392
  • 文/花漫 我一把揭開白布神郊。 她就那樣靜靜地躺著,像睡著了一般涌乳。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上宛乃,一...
    開封第一講書人閱讀 51,624評論 1 305
  • 那天蒸辆,我揣著相機與錄音,去河邊找鬼谆奥。 笑死逗宜,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的擂仍。 我是一名探鬼主播,決...
    沈念sama閱讀 40,358評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼逢渔,長吁一口氣:“原來是場噩夢啊……” “哼肃廓!你這毒婦竟也來了诲泌?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,261評論 0 276
  • 序言:老撾萬榮一對情侶失蹤哀蘑,失蹤者是張志新(化名)和其女友劉穎葵第,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體缀台,經(jīng)...
    沈念sama閱讀 45,722評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡膛腐,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了依疼。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片而芥。...
    茶點故事閱讀 40,030評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡棍丐,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出歌逢,到底是詐尸還是另有隱情,我是刑警寧澤砰苍,帶...
    沈念sama閱讀 35,737評論 5 346
  • 正文 年R本政府宣布阱高,位于F島的核電站,受9級特大地震影響吼旧,放射性物質(zhì)發(fā)生泄漏未舟。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,360評論 3 330
  • 文/蒙蒙 一员串、第九天 我趴在偏房一處隱蔽的房頂上張望昼扛。 院中可真熱鬧,春花似錦野揪、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽殴边。三九已至珍语,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間是偷,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評論 1 270
  • 我被黑心中介騙來泰國打工蛋铆, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留刺啦,地道東北人。 一個月前我還...
    沈念sama閱讀 48,237評論 3 371
  • 正文 我出身青樓玛瘸,卻偏偏與公主長得像糊渊,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子再来,可洞房花燭夜當晚...
    茶點故事閱讀 44,976評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 在一個方法內(nèi)部定義的變量都存儲在棧中芒篷,當這個函數(shù)運行結(jié)束后采缚,其對應(yīng)的棧就會被回收,此時扳抽,在其方法體中定義的變量將不...
    Y了個J閱讀 4,418評論 1 14
  • 函數(shù)式編程 引言 Scala中的函數(shù)是Java中完全沒有的概念贸呢。因為Java是完全面向?qū)ο蟮木幊陶Z言,沒有任何面向...
    義焃閱讀 1,278評論 2 5
  • 讀《快學Scala 》一書的摘要 Scala 運行于JVM之上怔鳖,擁有海量類庫和工具固蛾,兼顧函數(shù)式編程和面向?qū)ο蟆?在...
    abel_cao閱讀 1,280評論 0 8
  • Overview 本節(jié)主要介紹幾種語言中的數(shù)組和集合的對應(yīng)用法度陆。 數(shù)組在程序中一般用于表示一段連續(xù)的空間懂傀。通常來說...
    bookislife閱讀 953評論 0 0
  • 因個人主觀造成的問題變成客觀存在的問題的時候蜡感,再花多少時間主觀去懺悔,改正錯誤的時候铸敏,都無法回到過去,改變它的歷史...
    Jessica未央閱讀 194評論 0 0