自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

攜程中轉(zhuǎn)交通方案拼接性能優(yōu)化

人工智能 新聞
本文將結(jié)合實(shí)例,介紹在中轉(zhuǎn)交通拼接性能優(yōu)化過(guò)程中所遵循的原則、分析和優(yōu)化方法,旨在為讀者提供有價(jià)值的參考和啟示。

作者簡(jiǎn)介

簡(jiǎn)言,攜程后端開發(fā)經(jīng)理 ,關(guān)注技術(shù)架構(gòu)、性能優(yōu)化、交通規(guī)劃等領(lǐng)域。

一、背景介紹

由于交通規(guī)劃和運(yùn)力資源的限制,用戶查詢的兩地之間可能沒(méi)有直達(dá)交通,或者在重大節(jié)假日時(shí),直達(dá)交通都已售罄。不過(guò),通過(guò)火車、飛機(jī)、汽車、船舶等兩程或多程中轉(zhuǎn)的方式,用戶仍然可以到達(dá)目的地。此外,中轉(zhuǎn)交通有時(shí)在價(jià)格和耗時(shí)方面更具有優(yōu)勢(shì)。例如,對(duì)于從上海到運(yùn)城,通過(guò)火車中轉(zhuǎn)可能比直達(dá)火車更加快捷和便宜。

圖片

圖1 攜程火車中轉(zhuǎn)交通列表

在提供中轉(zhuǎn)交通方案時(shí),很重要的一個(gè)環(huán)節(jié)是將兩程或多程的火車、飛機(jī)、汽車、船舶等拼接起來(lái)組成可行的中轉(zhuǎn)方案。而中轉(zhuǎn)交通拼接的第一個(gè)難點(diǎn)是拼接空間極大,僅考慮上海做中轉(zhuǎn)城市,就可以產(chǎn)生近億種組合;另一個(gè)難點(diǎn)在于對(duì)實(shí)時(shí)性有要求,因?yàn)楫a(chǎn)線數(shù)據(jù)隨時(shí)變化,需要不斷地查詢火車、飛機(jī)、汽車、船舶的數(shù)據(jù)。中轉(zhuǎn)交通拼接需要大量的計(jì)算資源和IO開銷,因此,對(duì)其性能進(jìn)行優(yōu)化顯得尤為重要。

本文將結(jié)合實(shí)例,介紹在中轉(zhuǎn)交通拼接性能優(yōu)化過(guò)程中所遵循的原則、分析和優(yōu)化方法,旨在為讀者提供有價(jià)值的參考和啟示。

二、優(yōu)化原則

性能優(yōu)化需要在滿足業(yè)務(wù)需求的前提下,在各種資源和約束條件下去平衡和取舍,遵循一些大的原則有助于消除不確定性,去逼近解決問(wèn)題的最優(yōu)解。具體來(lái)說(shuō),中轉(zhuǎn)交通拼接優(yōu)化過(guò)程中主要遵循以下三個(gè)原則:

2.1 性能優(yōu)化是手段而不是目的

雖然本文是關(guān)于性能優(yōu)化的,但仍需要在最開始強(qiáng)調(diào):不要為了優(yōu)化而優(yōu)化。滿足業(yè)務(wù)需求的方式有很多,性能優(yōu)化只是其中一種。有時(shí)候問(wèn)題非常復(fù)雜,限制也很多,在不顯著影響用戶體驗(yàn)的前提下,通過(guò)放寬限制或采用其他流程來(lái)減少對(duì)用戶的影響,這也是解決性能問(wèn)題的好方法。在軟件開發(fā)中,存在許多通過(guò)犧牲少量性能來(lái)實(shí)現(xiàn)大幅降低成本的事例。例如,在Redis中用于基數(shù)統(tǒng)計(jì)(去重)的HyperLogLog算法,它在標(biāo)準(zhǔn)誤差為0.81%的前提下,只需要12K空間就能夠統(tǒng)計(jì)264的數(shù)據(jù)。

回到問(wèn)題本身,由于需要頻繁地查詢產(chǎn)線數(shù)據(jù),并且進(jìn)行海量的拼接操作,那么如果要求每個(gè)用戶查詢時(shí)都立刻返回最新鮮的中轉(zhuǎn)方案,成本將會(huì)非常高。為了降低成本,需要在響應(yīng)時(shí)間和數(shù)據(jù)新鮮度之間進(jìn)行平衡。經(jīng)過(guò)仔細(xì)考慮選擇可以接受分鐘級(jí)的數(shù)據(jù)不一致,對(duì)于一些冷門線路和日期,可能在首次查詢時(shí)沒(méi)有好的中轉(zhuǎn)方案,此時(shí)引導(dǎo)用戶重新刷新頁(yè)面即可。

2.2 不正確的優(yōu)化是萬(wàn)惡之源

Donald Knuth在《Structured Programming With Go To Statements》中提到:“程序員們浪費(fèi)大量的時(shí)間去思考、擔(dān)憂非關(guān)鍵路徑的性能,而嘗試優(yōu)化這部分性能,對(duì)整體代碼的調(diào)試和維護(hù)都有非常嚴(yán)重的負(fù)面影響,因此97%的情況,我們應(yīng)該忘記小的優(yōu)化點(diǎn)”。簡(jiǎn)而言之,在沒(méi)有發(fā)現(xiàn)真正的性能問(wèn)題之前,在代碼層面過(guò)度炫技式的優(yōu)化,不僅不會(huì)提高性能,反而可能會(huì)導(dǎo)致更多的錯(cuò)誤。然而作者同樣也強(qiáng)調(diào):“對(duì)于剩下關(guān)鍵的3%,我們也不要錯(cuò)過(guò)優(yōu)化的機(jī)會(huì)”。因此,需要時(shí)刻關(guān)注性能問(wèn)題,不做會(huì)影響性能的決策,并在必要的時(shí)候做正確的優(yōu)化。

2.3 量化分析性能,明確優(yōu)化方向

正如前一節(jié)所述,在進(jìn)行優(yōu)化之前,首先要量化性能并找出瓶頸,這樣優(yōu)化的才更有針對(duì)性。量化分析性能可以借助耗時(shí)監(jiān)控、Profiler性能分析工具、Benchmark基準(zhǔn)測(cè)試工具等,重點(diǎn)關(guān)注耗時(shí)特別長(zhǎng)或者執(zhí)行頻率特別高的地方。正如阿姆達(dá)爾定律所述:“系統(tǒng)中對(duì)某一部件采用更快執(zhí)行方式所能獲得的系統(tǒng)性能改進(jìn)程度,取決于這種執(zhí)行方式被使用的頻率,或所占總執(zhí)行時(shí)間的比例”。

此外,還需要注意到性能優(yōu)化是一場(chǎng)持久戰(zhàn)。隨著業(yè)務(wù)的不斷發(fā)展,架構(gòu)和代碼也不停地變化,因此更需要持續(xù)量化性能,不斷分析瓶頸和評(píng)估優(yōu)化效果。

三、性能分析之路

3.1 梳理業(yè)務(wù)流程

在性能分析之前,首先要梳理業(yè)務(wù)流程。中轉(zhuǎn)交通方案拼接主要包含以下四個(gè)步驟:

a.  加載線路圖,如北京經(jīng)南京中轉(zhuǎn)到上海,只考慮線路本身的信息,與具體的班次無(wú)關(guān);

b.  查火車、飛機(jī)、汽車、船舶的產(chǎn)線數(shù)據(jù),包括出發(fā)時(shí)間、到達(dá)時(shí)間、出發(fā)站、到達(dá)站、價(jià)格和余票信息等;

c.  拼接出所有可行的中轉(zhuǎn)交通方案,主要是考慮換乘時(shí)間不能過(guò)短,以免無(wú)法完成換乘;同時(shí)也不宜過(guò)長(zhǎng),以免等待太久。拼接出可行的方案后,還需要完善業(yè)務(wù)字段,例如總價(jià)格、總耗時(shí)和換乘信息等;

d.  根據(jù)一定的規(guī)則,從拼接出的所有可行中轉(zhuǎn)方案中篩選出一些用戶可能感興趣的方案。

3.2 量化分析性能

(1)增加耗時(shí)監(jiān)控?

耗時(shí)監(jiān)控是一種最直觀的從宏觀角度觀察各個(gè)階段耗時(shí)情況的手段。它不僅可以查看業(yè)務(wù)流程各階段的耗時(shí)值與耗時(shí)占比,還可以長(zhǎng)期觀察耗時(shí)變化趨勢(shì)。

耗時(shí)監(jiān)控可以借助公司內(nèi)部的指標(biāo)監(jiān)控告警系統(tǒng),在中轉(zhuǎn)交通方案拼接的主要流程中增加耗時(shí)打點(diǎn)。這些流程包括加載線路圖、查詢班次數(shù)據(jù)并進(jìn)行拼接、篩選和保存拼接方案等。各個(gè)階段的耗時(shí)情況如圖2所示,可以看到,拼接(含查產(chǎn)線數(shù)據(jù))的耗時(shí)占比最高,因此成為未來(lái)重點(diǎn)優(yōu)化的目標(biāo)。

圖片

圖2 中轉(zhuǎn)交通拼接耗時(shí)監(jiān)控

(2)Profiler性能分析?

耗時(shí)打點(diǎn)可能會(huì)侵入業(yè)務(wù)代碼,并對(duì)性能產(chǎn)生影響,因此不宜過(guò)多,更適合監(jiān)控主要流程。與之對(duì)應(yīng)的Profiler性能分析工具(例如Async-profiler),可以生成更具體的調(diào)用樹以及各函數(shù)的CPU占用比例,從而幫助關(guān)鍵路徑和性能瓶頸的分析與定位。

圖片

圖3 拼接調(diào)用樹與CPU占比

如圖3所示,拼接方案(combineTransferLines)占53.80%,查產(chǎn)線數(shù)據(jù)(querySegmentCacheable,已使用緩存)占21.45%。在拼接方案中, 計(jì)算方案評(píng)分(computeTripScore,占48.22%)、創(chuàng)建方案實(shí)體(buildTripBO,占4.61%)和檢查拼接可行性(checkCombineMatchCondition,占0.91%)是占比最大的三個(gè)環(huán)節(jié)。

圖片

圖4 方案打分調(diào)用樹和CPU占比

繼續(xù)分析占比最高的計(jì)算方案評(píng)分(computeTripScore)時(shí),發(fā)現(xiàn)主要與自定義的字符串格式化函數(shù)(StringUtils.format)有關(guān),包括直接調(diào)用(用于展示方案評(píng)分細(xì)節(jié)),以及通過(guò)getTripId間接調(diào)用(用于生成方案的ID)。自定義的StringUtils.format中占比最高的是java/lang/String.replace,Java 8原生的字符串替換是通過(guò)正則實(shí)現(xiàn)的,效率比較低(這一問(wèn)題在Java9之后已經(jīng)改進(jìn)了)。

// 計(jì)算方案評(píng)分(computeTripScore) 中調(diào)用的StringUtils.format代碼示例
StringUtils.format("AAAA-{0},BBBB-{1},CCCC-{2},DDDD-{3},EEEE-{4},FFFF-{5},GGGG-{6},HHHH-{7},IIII-{8},JJJJ-{9}",
aaaa, bbbb, cccc, dddd, eeee, ffff, gggg, hhhh, iiii, jjjj)


// getTripId 中調(diào)用StringUtils.format代碼示例
StringUtils.format("{0}_{1}_{2}_{3}_{4}_{5}_{6}", aaaa, bbbb, cccc, dddd, eeee, ffff)


// 通過(guò)Java replace實(shí)現(xiàn)的自定義format函數(shù)
public static String format(String template, Object... parameters) {
for (int i = 0; i < parameters.length; i++) {
template = template.replace("{" + i + "}", parameters[i] + "");
}
return template;
}

(3)Benchmark基準(zhǔn)測(cè)試?

借助Benchmark基準(zhǔn)測(cè)試工具可以更準(zhǔn)確地測(cè)量代碼的執(zhí)行時(shí)間。在表1中,我們通過(guò)JMH(Java Microbenchmark Harness)對(duì)三種字符串格式化方法和一種字符串拼接方法進(jìn)行耗時(shí)測(cè)試。測(cè)試結(jié)果表明,使用Java8的replace方法實(shí)現(xiàn)的字符串格式化性能最差,而使用Apache的字符串拼接函數(shù)性能最佳。

表1 字符串格式化與拼接性能對(duì)比

實(shí)現(xiàn)

執(zhí)行1000次平均耗時(shí)(us)

使用Java8的replace實(shí)現(xiàn)的StringUtils.format

1988.982

使用Apache replace實(shí)現(xiàn)的StringUtils.format

656.537

Java8自帶String.format

1417.474

Apache的StringUtils.join

116.812

四、性能優(yōu)化之路

通過(guò)以上的性能分析,我們發(fā)現(xiàn)拼接和查詢產(chǎn)線數(shù)據(jù)是性能瓶頸,字符串格式化影響尤其大。因此,我們將致力于優(yōu)化這些部分,以提高性能表現(xiàn)。

4.1 優(yōu)化代碼邏輯

優(yōu)化代碼邏輯是最簡(jiǎn)單且性價(jià)比最高的方法,可以是修正有問(wèn)題的代碼或替換為更好的實(shí)現(xiàn)。不同的實(shí)現(xiàn),哪怕減上幾納秒,累加起來(lái)也是很可觀的。借助一些經(jīng)典算法或數(shù)據(jù)結(jié)構(gòu)(如快速排序、紅黑樹等)可以在時(shí)間和空間復(fù)雜度方面帶來(lái)顯著優(yōu)勢(shì)?;氐街修D(zhuǎn)交通方案拼接性能優(yōu)化本身,優(yōu)化的代碼邏輯主要包括:

(1)優(yōu)化字符串拼接性能?

如前面的JMH的結(jié)果所示,自定義的字符串格式化函數(shù)性能最差,因此作為重點(diǎn)優(yōu)化目標(biāo)。優(yōu)化前后的對(duì)比如下所示:

// 優(yōu)化前,通過(guò)Java replace實(shí)現(xiàn)的format函數(shù)
public static String format(String template, Object... parameters) {
for (int i = 0; i < parameters.length; i++) {
template = template.replace("{" + i + "}", parameters[i] + "");
}
return template;
}
// 優(yōu)化后,通過(guò)Apache replace實(shí)現(xiàn)的format函數(shù)
public static String format(String template, Object... parameters) {
for (int i = 0; i < parameters.length; i++) {
String temp = new StringBuilder().append('{').append(i).append('}').toString();
template = org.apache.commons.lang3.StringUtils.replace(template, temp, String.valueOf(parameters[i]));
}
return template;
}

根據(jù)JMH的測(cè)試結(jié)果,即使是優(yōu)化后的格式化函數(shù),其性能也不是最優(yōu)的。在不顯著影響可讀性的前提下,應(yīng)盡量使用性能更優(yōu)的StringUtils.join函數(shù)。

// 優(yōu)化前
StringUtils.format("{0}_{1}_{2}_{3}_{4}_{5}_{6}", aaaa, bbbb, cccc, dddd, eeee, ffff)


// 優(yōu)化后
StringUtils.join("_", aaaa, bbbb, cccc, dddd, eeee, ffff)

為進(jìn)一步提升性能,可以在computeTripScore 函數(shù)中添加一個(gè)開關(guān),僅在調(diào)試模式下才展示評(píng)分細(xì)節(jié),這將確保該字符串格式化函數(shù)僅在需要時(shí)才被調(diào)用。

if (Config.getBoolean("enable.score.detail", false)) {
scoreDetail = StringUtils.format("AAAA-{0},BBBB-{1},CCCC-{2},DDDD-{3},EEEE-{4},FFFF-{5},GGGG-{6},HHHH-{7},IIII-{8},JJJJ-{9}",
aaaa, bbbb, cccc, dddd, eeee, ffff, gggg, hhhh, iiii, jjjj);
}

優(yōu)化后的CPU占比如圖5所示,此時(shí)字符串格式化已經(jīng)不再是性能瓶頸。

圖片

圖5 優(yōu)化后的拼接調(diào)用樹和CPU占比

(2)增加索引降低拼接時(shí)間復(fù)雜度?

圖片

圖6 增加索引降低拼接時(shí)間復(fù)雜度

在中轉(zhuǎn)拼接過(guò)程中,我們需要將第一程每個(gè)班次的到達(dá)時(shí)間與第二程每個(gè)班次的出發(fā)時(shí)間進(jìn)行比較,以判斷中轉(zhuǎn)時(shí)間是否過(guò)短或過(guò)長(zhǎng)。為簡(jiǎn)化說(shuō)明,假設(shè)換乘時(shí)間間隔需要滿足大于30分鐘且小于6小時(shí)。以北京到上海經(jīng)南京中轉(zhuǎn)的兩程火車為例,3月9日北京到南京有66個(gè)班次,南京到上海有275個(gè)班次,考慮到隔夜車,還需要算上3月10日南京到上海的275個(gè)班次,那么最多需要比較36300(66*275*2)次。

為避免頻繁比較,參考了MySQL B+樹索引的思想,將第二程南京到上海的所有火車班次數(shù)據(jù)構(gòu)建成紅黑樹。其中,樹的鍵為秒級(jí)時(shí)間戳,例如2023-03-09 11:29出發(fā)的G367鍵為1677247680,值為G367的班次數(shù)據(jù)。有了索引樹,最多只需要10次比較,就可以找到最近的滿足最小換乘時(shí)間要求的班次。同理,最多需要10次比較,就能找到滿足最大換乘時(shí)間要求的最晚班次。兩者之間的所有班次都滿足耗時(shí)要求,直接進(jìn)行拼接即可。改進(jìn)后最多需要比較1320(66*(10+10))次,約為原來(lái)的1/27.5。

(3)使用多路歸并求Top-K算法?

在篩選方案時(shí),會(huì)存在以下場(chǎng)景:有多個(gè)中轉(zhuǎn)點(diǎn),每個(gè)中轉(zhuǎn)點(diǎn)都有數(shù)百個(gè)得分較高的方案(內(nèi)部已按得分由高到低排序,通過(guò)小根堆實(shí)現(xiàn))。最終需要將這些方案合并,并從中篩選出得分最高的K個(gè)方案。

最簡(jiǎn)單的方法是使用快速排序?qū)⑺械姆桨概判?,然后選取前K個(gè),時(shí)間復(fù)雜度約為O(nlog2n)。然而,這并沒(méi)有利用到每個(gè)隊(duì)列自身有序的特點(diǎn)。通過(guò)多路歸并算法時(shí)間復(fù)雜度可降為O(nlog2k),具體步驟為:

a.  從每個(gè)隊(duì)列中拿出第一個(gè)元素(得分最高的方案),放入大根堆中;

b.  從大根堆堆頂拿出最大的元素,放到結(jié)果集中;

c.  如果該元素所在的隊(duì)列還有剩余元素,則將下一個(gè)元素加入堆中;

d.  重復(fù)步驟2和3,直到結(jié)果集中包含K個(gè)元素或所有的隊(duì)列都為空。

圖片

圖7 多路歸并求Top-K算法

4.2 構(gòu)建多級(jí)緩存

緩存是一種典型的以空間換時(shí)間策略,可以緩存數(shù)據(jù)和計(jì)算結(jié)果,緩存數(shù)據(jù)可以提高訪問(wèn)效率,緩存結(jié)果避免了重復(fù)計(jì)算。緩存在帶來(lái)性能提升的同時(shí),又會(huì)引入新的問(wèn)題:

  • 緩存容量有限,需要仔細(xì)斟酌數(shù)據(jù)的加載、更新、失效和替換策略;
  • 緩存架構(gòu)的設(shè)計(jì):通常來(lái)說(shuō)內(nèi)存緩存(如HashMap、Caffeine等)性能最高,而Redis等分布式緩存次之,RocksDB相對(duì)較慢,容量上限則正好相反,需要仔細(xì)選型并搭配使用;
  • 緩存不一致問(wèn)題如何解決,能接受多久的不一致。

在中轉(zhuǎn)交通方案拼接過(guò)程中,需要使用大量的基礎(chǔ)數(shù)據(jù)(如車站、行政區(qū)域等),以及海量的動(dòng)態(tài)數(shù)據(jù)(例如班次數(shù)據(jù))。綜合以上因素并結(jié)合中轉(zhuǎn)交通拼接的業(yè)務(wù)特點(diǎn),緩存架構(gòu)做如下設(shè)計(jì):

  • 基礎(chǔ)數(shù)據(jù)(如車站、行政區(qū)域等),因數(shù)據(jù)量小,變化頻率低,全量保存到HashMap中,周期全量更新;
  • 部分火車、飛機(jī)、汽車、船舶的班次數(shù)據(jù)緩存到Redis中,以提高訪問(wèn)效率和穩(wěn)定性。不同產(chǎn)線采取的緩存策略稍有不同,但總的來(lái)說(shuō)是定時(shí)更新與搜索觸發(fā)更新相結(jié)合的方式;
  • 一次拼接過(guò)程中可能查詢數(shù)百次產(chǎn)線數(shù)據(jù),Redis毫秒級(jí)的延遲累加起來(lái)也是非常大的。因此,希望在Redis之上再構(gòu)建一層內(nèi)存緩存以提高性能。通過(guò)分析發(fā)現(xiàn)拼接過(guò)程中存在非常明顯的熱點(diǎn)數(shù)據(jù),熱門日期和線路的查詢占比非常高且數(shù)量相對(duì)有限。因此可以將這部分熱點(diǎn)數(shù)據(jù)保存到內(nèi)存緩存中,使用LFU(Least Frequently Used)替換,最終產(chǎn)線數(shù)據(jù)內(nèi)存緩存命中率達(dá)到45%以上,相當(dāng)于降低近一半的IO開銷。
  • 因?yàn)榭梢越邮芊昼娂?jí)的數(shù)據(jù)不一致,所以將拼接結(jié)果緩存起來(lái),在有效期內(nèi),如果下一個(gè)用戶查詢同一出發(fā)日期的相同線路,直接使用緩存數(shù)據(jù)即可。因?yàn)槠唇拥闹修D(zhuǎn)方案數(shù)據(jù)相對(duì)較大,所以將拼接結(jié)果保存到RocksDB中,雖然性能不如Redis,但是對(duì)于單次查詢影響還可以接受。

圖片

圖8 多級(jí)緩存結(jié)構(gòu)

4.3 預(yù)處理

盡管理論上可以選擇任意城市作為兩地的中轉(zhuǎn)點(diǎn),但實(shí)際上大部分中轉(zhuǎn)城市都無(wú)法拼接出優(yōu)質(zhì)的方案。因此,先通過(guò)離線預(yù)處理篩選出部分高質(zhì)量的中轉(zhuǎn)點(diǎn),從而將求解空間從幾千降至數(shù)十。相對(duì)于動(dòng)態(tài)變化的班次,線路數(shù)據(jù)是相對(duì)固定的,每天計(jì)算一次即可。此外離線預(yù)處理可以借助大數(shù)據(jù)技術(shù),處理海量數(shù)據(jù),相對(duì)對(duì)耗時(shí)不敏感。

4.4 多線程處理

在一次拼接過(guò)程中,需要處理數(shù)十條不同中轉(zhuǎn)點(diǎn)的線路。每個(gè)線路的拼接是相互獨(dú)立的,因此可以采用多線程處理,這樣可以最大程度地降低處理時(shí)間。但受線路班次數(shù)量和緩存命中率的影響,不同線路的拼接耗時(shí)很難一致。很多時(shí)候,分配相同任務(wù)數(shù)量的兩個(gè)線程,即使一個(gè)線程很快執(zhí)行完,也要等待另外一個(gè)線程執(zhí)行完才能進(jìn)行下一步操作。為避免這種情況,這里借助ForkJoinPool的work-stealing機(jī)制。這個(gè)機(jī)制可以確保每個(gè)線程在完自己的任務(wù)后,還會(huì)分擔(dān)其他線程未完成的工作,提高并發(fā)效率,減少空閑時(shí)間。

但是多線程也不是萬(wàn)能的,使用時(shí)需要注意:

  • 子任務(wù)的執(zhí)行需要相互獨(dú)立、互不影響。如果存在依賴關(guān)系,則需要等待前一個(gè)任務(wù)執(zhí)行完才能開始下一個(gè)任務(wù),這樣會(huì)使多線程失去意義;
  • CPU核數(shù)決定了并發(fā)能力的上限,過(guò)多的線程會(huì)因頻繁切換上下文而降低性能,需要特別關(guān)注線程數(shù)、CPU使用率、CPU Throttled time等指標(biāo)。

4.5 延遲計(jì)算

通過(guò)將計(jì)算推遲到必要的時(shí)刻,可能避免很多多余的開銷。例如,在拼接完中轉(zhuǎn)方案后,需要構(gòu)建方案實(shí)體并完善業(yè)務(wù)字段,這部分也比較消耗資源。而且并非所有拼接的方案都會(huì)被篩選出來(lái),這意味著這部分未被篩選的方案仍然需要耗費(fèi)計(jì)算資源。因此延遲完整方案實(shí)體對(duì)象的構(gòu)建,先將拼接過(guò)程中的數(shù)以萬(wàn)計(jì)的方案保存為輕量的中間對(duì)象,只對(duì)篩選之后的數(shù)百個(gè)中間對(duì)象構(gòu)建完整的方案實(shí)體。

4.6 JVM優(yōu)化

中轉(zhuǎn)交通拼接項(xiàng)目是基于Java 8的,并使用G1(Garbage-First)垃圾收集器,部署在8C8G機(jī)器上。G1在實(shí)現(xiàn)高吞吐量的同時(shí)盡可能滿足停頓時(shí)間的要求,系統(tǒng)架構(gòu)部門設(shè)置的默認(rèn)參數(shù)已經(jīng)能夠適用于大多數(shù)場(chǎng)景,通常不需要專門的優(yōu)化。

但有些線路中轉(zhuǎn)方案過(guò)多,導(dǎo)致報(bào)文太大,超過(guò)Region大小的一半(8G 默認(rèn)Region大小是2M),導(dǎo)致很多應(yīng)該進(jìn)入年輕代的大對(duì)象直接進(jìn)入了老年代,為了避免這種情況,將Region大小改為16M。

五、總結(jié)

通過(guò)以上的分析和優(yōu)化,拼接耗時(shí)變化如圖9所示:

圖片

圖9 中轉(zhuǎn)交通方案拼接性能優(yōu)化效果

雖然每個(gè)業(yè)務(wù)和場(chǎng)景都有各自的特點(diǎn),性能優(yōu)化時(shí)也需要具體分析。但原理是相通的,依然可以參考本文所述的分析和優(yōu)化方法。本文所有的分析和優(yōu)化方法總結(jié)如圖10所示。

圖片

圖10 中轉(zhuǎn)交通方案拼接優(yōu)化總結(jié)

責(zé)任編輯:張燕妮 來(lái)源: 攜程技術(shù)
相關(guān)推薦

2022-07-15 09:20:17

性能優(yōu)化方案

2022-07-08 09:38:27

攜程酒店Flutter技術(shù)跨平臺(tái)整合

2016-09-01 09:39:20

攜程無(wú)線

2021-09-17 12:54:05

AI 數(shù)據(jù)人工智能

2023-06-09 09:54:36

攜程工具

2014-12-25 17:51:07

2013-12-02 15:37:18

華為浙大中控智慧交通

2022-03-30 18:39:51

TiDBHTAPCDP

2023-07-07 14:18:57

攜程實(shí)踐

2022-09-09 15:49:03

攜程火車票組件化管理優(yōu)化

2022-04-07 17:30:31

Flutter攜程火車票渲染

2022-10-27 09:42:22

數(shù)據(jù)庫(kù)SQL

2016-10-11 14:57:33

攜程APP性能優(yōu)化

2022-08-12 08:38:08

攜程小程序Taro跨端解決方案

2022-07-15 12:58:02

鴻蒙攜程華為

2014-12-24 10:45:05

攜程

2019-03-01 11:03:22

Lustre高性能計(jì)算

2022-05-13 09:27:55

Widget機(jī)票業(yè)務(wù)App

2013-10-15 14:43:01

2023-07-07 14:12:52

攜程開發(fā)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)