簡體   English   中英

Java - 檢查String大小的最快方法

[英]Java - Fastest way to check the size of String

我在循環語句中有以下代碼。
在循環中,字符串被附加到sb(StringBuilder)並檢查sb的大小是否已達到5MB。

if (sb.toString().getBytes("UTF-8").length >= 5242880) {
    // Do something
}

這工作正常,但它很慢(在檢查大小方面)
最快的方法是什么?

您可以使用快速計算UTF-8長度

public static int utf8Length(CharSequence cs) {
    return cs.codePoints()
        .map(cp -> cp<=0x7ff? cp<=0x7f? 1: 2: cp<=0xffff? 3: 4)
        .sum();
}

如果ASCII字符在內容中占主導地位,則使用起來可能會稍快一些

public static int utf8Length(CharSequence cs) {
    return cs.length()
         + cs.codePoints().filter(cp -> cp>0x7f).map(cp -> cp<=0x7ff? 1: 2).sum();
}

代替。

但是你也可以考慮不重新計算整個大小的優化潛力,而只考慮你追加到StringBuilder的新片段的大小,類似的東西

    StringBuilder sb = new StringBuilder();
    int length = 0;
    for(…; …; …) {
        String s = … //calculateNextString();
        sb.append(s);
        length += utf8Length(s);
        if(length >= 5242880) {
            // Do something

            // in case you're flushing the data:
            sb.setLength(0);
            length = 0;
        }
    }

這假設如果你附加包含代理對的片段,它們總是完整的並且不會被分成兩半。 對於普通應用,情況應始終如此。

Didier-L建議的另一種可能性是推遲計算,直到您的StringBuilder達到閾值的長度除以3,如前所述, UTF-8長度不可能大於閾值。 但是,如果碰巧在某些執行中沒有達到threshold / 3 ,那么這將是有益的。

如果循環1000次,則會生成1000String,然后轉換為“UTF-8 Byte”數組,以獲得長度。

我會通過存儲第一個長度來減少轉換。 然后,在每個循環上,只獲取添加值的長度,然后這只是一個補充。

int length = sb.toString().getBytes("UTF-8").length;
for(String s : list){
    sb.append(s);
    length += s.getBytes("UTF-8").length;
    if(...){
    ...
    }
}

這將減少使用的內存和轉換成本

考慮使用ByteArrayOutputStream和OutputStreamWriter而不是StringBuilder。 使用ByteArrayOutputStream.size()來測試大小。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM