我在這里看到了很多有關Java Lambda性能的問題,但大多數問題都像“ Lambda稍快,但使用閉包時變慢”或“預熱與執行時間不同”或其他類似的問題。但是,我在這里碰到了一件很奇怪的事情??紤]這個LeetCode問題:給定一組不重疊的間隔,請在間隔中插入一個新間隔(必要時合并)。您可以假設間隔最初是根據其開始時間排序的。這個問題被貼上了標簽,所以我認為線性方法不是他們想要的。因此,我決定想出一種巧妙的方法,將二進制搜索與對輸入列表的修改相結合。現在,在修改輸入列表時,問題還不是很清楚,即使簽名需要返回對列表的引用,它也顯示為“插入”,但暫時不要擔心。這是完整的代碼,但是只有前幾行與此問題相關。我將其余的保留在這里,以便任何人都可以嘗試: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 }這種方法運行良好并得到了接受,但運行時間為80毫秒,而大多數解決方案為4-5毫秒和18-19毫秒。當我查找它們時,它們都是線性的并且非常原始。人們不會期望從標記為“困難”的問題中得到什么。但是問題來了:在最壞的情況下,我的解決方案也是線性的(因為添加/清除操作是線性時間)。為什么這么慢?然后我這樣做了: 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毫秒!這里發生了什么?不幸的是,我不知道LeetCode在什么樣的環境下運行什么樣的測試,但是仍然不是20倍嗎?
2 回答

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