簡體   English   中英

將ASCII byte []轉換為String

[英]Convert ASCII byte[] to String

我試圖將包含ASCII字符的byte []傳遞給log4j,使用明顯的表示法登錄到文件中。 當我簡單地傳入byt []時,它當然被視為一個對象,並且日志非常無用。 當我嘗試使用new String(byte[] data)將它們轉換為字符串時,我的應用程序的性能減半。

如何有效地傳遞它們,而不會導致將它們轉換為字符串的大約30us時間代價。

另外,為什么轉換它們需要這么長時間?

謝謝。

編輯

我應該補充一點,我在這里選擇延遲 - 是的,30us確實有所作為! 而且,這些數組從~100一直到幾千字節不等。

ASCII是少數可以轉換為UTF16 /從UTF16轉換而無需算術或表查找的編碼之一,因此可以手動轉換:

String convert(byte[] data) {
    StringBuilder sb = new StringBuilder(data.length);
    for (int i = 0; i < data.length; ++ i) {
        if (data[i] < 0) throw new IllegalArgumentException();
        sb.append((char) data[i]);
    }
    return sb.toString();
}

但要確保它確實 ASCII,否則你最終會變成垃圾。

你想要做的是延遲處理byte []數組,直到log4j確定它實際上想要記錄消息。 這樣,您可以在DEBUG級別將其記錄,例如,在測試期間,然后在生產期間禁用它。 例如,您可以:

final byte[] myArray = ...;
Logger.getLogger(MyClass.class).debug(new Object() {
    @Override public String toString() {
        return new String(myArray);
    }
});

現在你不支付速度懲罰,除非你實際記錄數據,因為在log4j決定它實際上會記錄消息之前不會調用toString方法!

現在我不確定“明顯的表示”是什么意思所以我假設您的意思是通過將字節重新解釋為默認字符編碼來轉換為String。 現在,如果你正在處理二進制數據,這顯然是毫無價值的。 在這種情況下,我建議使用Arrays.toString(byte [])來創建一個格式化的字符串

[54, 23, 65, ...]

如果您的數據實際上是ASCII(即7位數據),那么您應該使用new String(data, "US-ASCII")而不是依賴於平台默認編碼。 這可能比嘗試將其解釋為您的平台默認編碼(可能是UTF-8,需要更多內省)更快。

您還可以通過緩存Charset實例並調用new String(data, charset)來避免每次Charset-Lookup命中來加快速度。

話雖如此:自從我在生產環境中看到真正的ASCII數據以來,已經很長很長時間了

表現減半? 這個字節數組有多大? 如果它是例如1MB,那么肯定有更多的因素需要考慮,而不僅僅是從字節“轉換”到字符(雖然它應該足夠快)。 1MB數據而不是“僅”100 byte[].toString()byte[].toString() 。toString( byte[].toString()可能生成) 寫入日志文件顯然需要一些時間。 磁盤文件系統沒有RAM內存快。

您需要更改字節數組的字符串表示形式。 也許有一些更敏感的信息,例如與之關聯的名稱(文件名?),其長度等等。 畢竟,該字節數組實際代表什么?

編輯 :我不記得在你的問題中看過“大約30us”的短語,也許你在詢問后的5分鍾內編輯了它,但這實際上是微觀優化,它一定不會導致“減半的表現”。 除非你每秒寫入一百萬次(那么,你為什么要這樣做呢?難道你沒有過度使用“記錄”現象嗎?)。

暫無
暫無

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

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