成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

用 JMH 檢測(cè) Lambdas 序列化性能

whatsns / 802人閱讀

摘要:本文將介紹如何進(jìn)行序列化性能檢測(cè)的重要性以及在分布式系統(tǒng)中的應(yīng)用。另一個(gè)鮮有人知的特點(diǎn)就是可被序列化。所以當(dāng)?shù)氖褂迷斐尚阅軉?wèn)題時(shí),就要使用備選方案。下面就是當(dāng)在中序列化時(shí),非采集的的情況。

本文將介紹如何進(jìn)行 Java Lambdas 序列化性能檢測(cè)、Lambdas 的重要性以及 Lambdas 在分布式系統(tǒng)中的應(yīng)用。

Lambdas 表達(dá)式是 Java 8 中萬(wàn)眾期待的新特性,其若干用途包括:

為匿名內(nèi)部類(lèi)減少所需樣本代碼。

縮小值的作用域。Lambdas 表達(dá)式中的 this 不會(huì)涉及到外部類(lèi),減少了內(nèi)存泄露。

輕松集成現(xiàn)有 API 與新的 Streams API。

Lambdas 另一個(gè)鮮有人知的特點(diǎn)就是可被序列化。

為什么對(duì) Lambda 序列化?

序列化有益于對(duì)象的狀態(tài)持久化和網(wǎng)絡(luò)傳輸。 Lambdas 應(yīng)該盡可能無(wú)狀態(tài),這樣就可以保存 Lambdas ,但這并不是典型的用例。

Lambdas 表達(dá)式的目的是給程序庫(kù)傳遞代碼片段,使之與庫(kù)中正在運(yùn)行的程序交互。但是如果程序庫(kù)支持像 Chronicle Engine 這樣的分布式系統(tǒng),那又會(huì)怎么樣?

什么是 Chronicle Engine?

Chronicle Engine 是一個(gè)庫(kù),可讓用戶使用各自的應(yīng)用程序遠(yuǎn)程訪問(wèn)數(shù)據(jù)結(jié)構(gòu),無(wú)論是用 Java、C# 客戶端,還是用 NFS 文件系統(tǒng)。該庫(kù)還支持存儲(chǔ)和持久化數(shù)據(jù),也支持復(fù)制。

分布式系統(tǒng)中的 Lambdas

對(duì)于某些局部運(yùn)行的操作,使用 Lambdas 執(zhí)行不失為一種簡(jiǎn)單可行的方法。示例操作如下:

MapView map = acquireMap(“map-name”, 
                                      String.class, Long.class);
map.put(“key”, 1);
long ret = map.applyToKey(“key”, v -> v + 1); // ret == 2

這里沒(méi)有必要知道數(shù)據(jù)的具體存儲(chǔ)位置,如果是遠(yuǎn)程服務(wù)器,就會(huì)在那臺(tái)服務(wù)器上對(duì) Lambda 序列化,然后執(zhí)行,并將結(jié)果返回。

上圖顯示了 OneAPM 如何監(jiān)控和讓 Java 應(yīng)用之間的調(diào)用關(guān)系可視化。

Capturing Lambda

不獲取字段的 Lambda 可以被 Java 更高效地處理,因?yàn)槊總€(gè)實(shí)例都一樣,所以并不需要每次都創(chuàng)建新的對(duì)象。但是,若編譯時(shí) Lambda 獲取到未知值,就需要?jiǎng)?chuàng)建新的對(duì)象,并將獲取的值保存。

Non capturing Lambda

Function appendStar = s -> s + "*"

Capturing Lambda

String star = "*";
    Function appendStar = s -> s + star;
可序列化的 Lambdas

Lambdas 默認(rèn)是不可序列化的,必須實(shí)現(xiàn)一種可序列化的接口。可以使用強(qiáng)制轉(zhuǎn)換把接口類(lèi)型轉(zhuǎn)換為所需類(lèi)型的一種方式。

Function appendStar = 
     (Function & Serializable) (s -> s + star);

筆者個(gè)人不喜歡這樣做,因?yàn)檫@樣會(huì)破壞減少代碼的目標(biāo)。一個(gè)解決的方法就是定義自己所需的可序列化的接口。

@FunctionalInterface
public interface SerializableFunction 
       extends Function, Serializable {

這就需要如下所寫(xiě):

SerializableFunction appendStar = s -> s + star;

或者按照這種方法寫(xiě)入:

 R applyToKey(K key, @NotNull SerializableFunction function) {

該庫(kù)的調(diào)用者就可以如下所寫(xiě),而不需要任何樣本代碼。

String s = map.applyToKey(“key”, s-> s + “*”);
Lambdas 的實(shí)時(shí)查詢(xún)

利用序列化的 Lambdas,可進(jìn)行如下所示的實(shí)時(shí)查詢(xún):

// print the last name of all the people in NYC
    acquireMap(“people”, String.class, Person.class).query()
    .filter(p -> p.getCity().equals(“NYC”)) // executed on the server
    .map(p → p.getLastName())  // executed on the server
    .subscribe(System.out::println); // executed on the client.

可查詢(xún)接口是必需的,因此過(guò)濾器 Predicate 和 map 函數(shù)也必須隱式可序列化。如果需要使用 Streams API,那就要使用早期較為復(fù)雜的數(shù)據(jù)類(lèi)型轉(zhuǎn)換函數(shù) cast。

序列化 Lambdas 的性能

筆者曾經(jīng)在一個(gè)字符串中寫(xiě)入符號(hào)“*”,并使用 JMH 對(duì)簡(jiǎn)單的序列化的和反序列化的 Lambda 進(jìn)行時(shí)延采樣,然后比較采集和非采集兩種情況下的時(shí)延,發(fā)送枚舉時(shí)兩種情況下的時(shí)延也一并比較。代碼和結(jié)果如下表所示:

99.99%的時(shí)延意味著該試驗(yàn)的99.99%都是在時(shí)延之中。時(shí)間都用微秒計(jì)算。

Test Typical latency 99.99% latency
Java Serialization, non-capturing 33.9 μs 215 μs
Java Serialization, capturing 36.3 μs 704 μs
Java Serialization, with an enum 7.9 μs 134 μs
Chronicle Wire (Text), non-capturing 20.4 μs 147 μs
Chronicle Wire (Text), capturing 22.5 μs 148 μs
Chronicle Wire (Text), with an enum 1.2 μs 5.9 μs
Chronicle Wire (Binary), non-capturing 11.7 μs 103 μs
Chronicle Wire (Binary), capturing 12.7 μs 135 μs
Chronicle Wire (Binary), with an enum 1.0 μs 1.2 μs
為什么要使用枚舉?

使用 Lambda 是很簡(jiǎn)單,但它效率不高時(shí),就需要找一個(gè)備選方案。所以當(dāng) Lambda 的使用造成性能問(wèn)題時(shí),就要使用備選方案。

enum Functions implements SerializableFunction {
    APPEND_STAR {
        @Override
        public String apply(String s) {
            return s + "*";
        }
    }
}

為考察使用枚舉所起到的作用,可以比較發(fā)送到服務(wù)器的數(shù)據(jù)量的多少,在那里可以看到所有序列化的數(shù)據(jù)。
下面就是當(dāng)在 TextWire 中序列化時(shí),非采集的 Lambda 的情況。(基于 YAML)

!SerializedLambda {
  cc: !type lambda.LambdaSerialization,
  fic: net/openhft/chronicle/core/util/SerializableFunction,
  fimn: apply,
  fims: (Ljava/lang/Object;)Ljava/lang/Object;,
  imk: 6,
  ic: lambda/LambdaSerialization,
  imn: lambda$textWireSerialization$ea1ad110$1,
  ims: (Ljava/lang/String;)Ljava/lang/String;,
  imt: (Ljava/lang/String;)Ljava/lang/String;,
  ca: [
  ]
}

枚舉序列化如下所示:

!Functions APPEND_STAR

注意:當(dāng)需要采集某些值時(shí),不可以使用枚舉。我們要做的就是讓你通過(guò)傳遞有附加參數(shù)的枚舉,以獲得最有效的組合。

使用枚舉就像存儲(chǔ)過(guò)程

用枚舉代替 Lambdas 的一個(gè)好處就是,可以跟蹤所有功能客戶執(zhí)行和整合的方式。某些函數(shù)使用廣泛,運(yùn)用枚舉使得修復(fù)任一多帶帶函數(shù)中產(chǎn)生的bug更為容易,因此會(huì)被經(jīng)常使用。舉一個(gè)簡(jiǎn)單的例子,MapFunction 起初有很多不同的 Lambdas,而現(xiàn)在已經(jīng)被歸為一類(lèi)。

結(jié)論

如果所使用的 API 支持,可將 Lambdas 用于分布式應(yīng)用程序。如果需要附加的性能,也可以使用枚舉。

原文地址:https://dzone.com/articles/measuring-the-serialization-performance-of-lambdas

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/65313.html

相關(guān)文章

  • Java 8 的 JVM 有多快?Fork-Join 性能基準(zhǔn)測(cè)試

    摘要:這減輕了手動(dòng)重復(fù)執(zhí)行相同基準(zhǔn)測(cè)試的痛苦,并簡(jiǎn)化了獲取結(jié)果的流程。處理項(xiàng)目的代碼并從標(biāo)有注釋的方法處生成基準(zhǔn)測(cè)試程序。用和運(yùn)行該基準(zhǔn)測(cè)試得到以下結(jié)果。同時(shí),和的基線測(cè)試結(jié)果也有略微的不同。 Java 8 已經(jīng)發(fā)布一段時(shí)間了,許多開(kāi)發(fā)者已經(jīng)開(kāi)始使用 Java 8。本文也將討論最新發(fā)布在 JDK 中的并發(fā)功能更新。事實(shí)上,JDK 中已經(jīng)有多處java.util.concurrent 改動(dòng),但...

    Euphoria 評(píng)論0 收藏0
  • 使JMH對(duì)比BeanUtils和BeanCopier

    摘要:背景許多時(shí)候需要對(duì)比不同的框架或工具或算法,選擇使用性能更優(yōu)的那一個(gè)。通常的做法是但這樣的做法非常不嚴(yán)謹(jǐn),因?yàn)楫?dāng)獨(dú)立頻繁運(yùn)行這一小塊代碼時(shí),可能會(huì)針對(duì)性的做一些優(yōu)化工作,而在實(shí)際的生產(chǎn)環(huán)境中是不會(huì)有此優(yōu)化的。 背景 許多時(shí)候需要對(duì)比不同的框架或工具或算法, 選擇使用性能更優(yōu)的那一個(gè)。通常的做法是 long start = System.currentTimeMillis(); for(...

    yuxue 評(píng)論0 收藏0
  • 漫談Exception與Result

    摘要:分析性能的影響但是需要注意時(shí)間單位,只是微秒而已,毫秒的千分之一秒的百萬(wàn)分之一。在這種情況下,優(yōu)化毫秒的性能隱患無(wú)異于撿了芝麻丟了西瓜。 同步自:https://sulin.me/2019/T2ZXZB.... 在分布式系統(tǒng)開(kāi)發(fā)中,我們經(jīng)常需要將各種各樣的狀態(tài)碼、錯(cuò)誤信息傳遞給最外層的調(diào)用方,這個(gè)調(diào)用方通常是http/api接口,錯(cuò)誤信息比如登錄失效、參數(shù)錯(cuò)誤等等。 最外層接口暴露的...

    張利勇 評(píng)論0 收藏0
  • Java8 新特性:Lambda表達(dá)式和虛擬擴(kuò)展方法標(biāo)注

    摘要:摘要添加了表達(dá)式閉包和特性支持,包括方法的引用,增強(qiáng)類(lèi)型推斷,和虛擬擴(kuò)展方法。圍繞的語(yǔ)言功能支持包括虛擬擴(kuò)展方法,這將使接口的源代碼和二進(jìn)制兼容的方式演變升級(jí)。 Author:Joseph D. Darcy Organization:Oracle Owner:Brian Goetz Created:2011/11/1 Updated:2013/2/21 Type:Feature Sta...

    UsherChen 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<