我在這里看到了很多有關(guān)Java Lambda性能的問題,但大多數(shù)問題都像“ Lambda稍快,但使用閉包時(shí)變慢”或“預(yù)熱與執(zhí)行時(shí)間不同”或其他類似的問題。但是,我在這里碰到了一件很奇怪的事情。考慮這個(gè)LeetCode問題:給定一組不重疊的間隔,請(qǐng)?jiān)陂g隔中插入一個(gè)新間隔(必要時(shí)合并)。您可以假設(shè)間隔最初是根據(jù)其開始時(shí)間排序的。這個(gè)問題被貼上了標(biāo)簽,所以我認(rèn)為線性方法不是他們想要的。因此,我決定想出一種巧妙的方法,將二進(jìn)制搜索與對(duì)輸入列表的修改相結(jié)合。現(xiàn)在,在修改輸入列表時(shí),問題還不是很清楚,即使簽名需要返回對(duì)列表的引用,它也顯示為“插入”,但暫時(shí)不要擔(dān)心。這是完整的代碼,但是只有前幾行與此問題相關(guān)。我將其余的保留在這里,以便任何人都可以嘗試:public List<Interval> insert(List<Interval> intervals, Interval newInterval) { int start = Collections.binarySearch(intervals, newInterval, (i1, i2) -> Integer.compare(i1.start, i2.start)); int skip = start >= 0 ? start : -start - 1; int end = Collections.binarySearch(intervals.subList(skip, intervals.size()), new Interval(newInterval.end, 0), (i1, i2) -> Integer.compare(i1.start, i2.start)); if (end >= 0) { end += skip; // back to original indexes } else { end -= skip; // ditto }這種方法運(yùn)行良好并得到了接受,但運(yùn)行時(shí)間為80毫秒,而大多數(shù)解決方案為4-5毫秒和18-19毫秒。當(dāng)我查找它們時(shí),它們都是線性的并且非常原始。人們不會(huì)期望從標(biāo)記為“困難”的問題中得到什么。但是問題來了:在最壞的情況下,我的解決方案也是線性的(因?yàn)樘砑?清除操作是線性時(shí)間)。為什么這么慢?然后我這樣做了: Comparator<Interval> comparator = new Comparator<Interval>() { @Override public int compare(Interval i1, Interval i2) { return Integer.compare(i1.start, i2.start); } }; int start = Collections.binarySearch(intervals, newInterval, comparator); int skip = start >= 0 ? start : -start - 1; int end = Collections.binarySearch(intervals.subList(skip, intervals.size()), new Interval(newInterval.end, 0), comparator);從80毫秒降低到4毫秒!這里發(fā)生了什么?不幸的是,我不知道LeetCode在什么樣的環(huán)境下運(yùn)行什么樣的測試,但是仍然不是20倍嗎?
2 回答

幕布斯7119047
TA貢獻(xiàn)1794條經(jīng)驗(yàn) 獲得超8個(gè)贊
在我的計(jì)算機(jī)上進(jìn)行的快速測試表明,JDK 8和JDK 11之間的首次初始化已提高了四倍,但尚不清楚這是專用的lambda優(yōu)化還是總體加速的結(jié)果。它仍然不只是單個(gè)內(nèi)部類的初始化,但請(qǐng)注意,我們所談?wù)摰氖菣C(jī)器上約10 ms的一次性開銷。同樣,您只有在沒有人使用它們時(shí)才注意到它。只需--module-path
在命令行上指定a即可使其消失;顯然,代碼處理應(yīng)用程序模塊確實(shí)使用了lambda表達(dá)式。
添加回答
舉報(bào)
0/150
提交
取消