假設我有一個方法void foo(byte[] bytes)
需要一個字節數組作爲其參數。在Protobuf中,字節數組的Java類型Howerver是ByteString
。我可以使用byte[] toByteArray()
獲取字節數組。但問題是這種方法使用拷貝來構建新的陣列,這是相對昂貴的。我寧願直接返回底層數組,或者返回一個視圖。協議緩衝區:從ByteString獲取字節數組而不復制
是否有任何API,或性能處罰是可以接受的?
假設我有一個方法void foo(byte[] bytes)
需要一個字節數組作爲其參數。在Protobuf中,字節數組的Java類型Howerver是ByteString
。我可以使用byte[] toByteArray()
獲取字節數組。但問題是這種方法使用拷貝來構建新的陣列,這是相對昂貴的。我寧願直接返回底層數組,或者返回一個視圖。協議緩衝區:從ByteString獲取字節數組而不復制
是否有任何API,或性能處罰是可以接受的?
通常這是不可能的,因爲在ByteString
的某些子類中可能沒有這樣的數組。 BoundedByteString
可以包含更大的數組,因此需要進行復制才能獲得正確大小的數組。 RopeByteString
由其他字節串組成,因此需要複製以將其內容放入一個數組中。 LiteralByteString
將其內容存儲在正確大小的數組中,但它不提供直接訪問它的方法。
但最有可能的toByteArray()
將足夠快,因爲您的需求System.arraycopy()
是非常快的。
如果您確實因長陣列複製而導致性能問題,並且您不想直接通過ByteString
,請參閱asReadOnlyByteBuffer()
和asReadOnlyByteBufferList()
方法。他們將ByteString
內容包裝到ByteBuffer
中而不復制它們。
你不能從一個ByteString
沒有byte[]
複製,因爲這將允許你修改ByteString
的內容,這意味着ByteString
再也不能保證它是不可改變的。這很像爲什麼你不能在不復制的情況下從String
得到char[]
,即使String
實際上是由char[]
支持的。這可能是一個安全問題:在安全域之間傳遞String
或ByteString
時,重要的是接收方可以知道發件人在使用它時並未從其下方修改字符串。
但是,您可以撥打asReadOnlyByteBufferList()
獲得代表底層數據的ByteBuffer
,因爲ByteBuffer
強制執行不變性。
foo(byte [] bytes)方法做什麼?你能改變它的實現嗎? – kostya
@kostya您的意思是我可以使用'ByteString#writeTo(OutputStream)'而不是?但我真的希望我的模塊相互分離。 – duleshi
是的,就像'writeTo'。 'OutputStream'是標準庫中的一個類,所以你仍然可以保持foo()方法protobuf免費。 'ByteString'的Javadocs清楚地表明你所要求的是不可能的:像'String'一樣,ByteString的內容永遠不會被改變,即使在數據競爭或客戶端代碼中API使用不正確的情況下。 – kostya