Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The difference between Bytes and Array[Byte] #466

Open
zxch3n opened this issue Feb 10, 2025 · 15 comments
Open

The difference between Bytes and Array[Byte] #466

zxch3n opened this issue Feb 10, 2025 · 15 comments
Labels
documentation Improvements or additions to documentation question Further information is requested

Comments

@zxch3n
Copy link

zxch3n commented Feb 10, 2025

Why the conversion between them is not free?

@peter-jerry-ye
Copy link
Collaborator

The Array[Byte] is mutable while Bytes are not.

@peter-jerry-ye
Copy link
Collaborator

If you have a free conversion then you might write this erronous code:

fn main {
  let bytes : Array[Bytes] = [b'\x00', b'\x01', b'\x02']
  let content : Bytes = bytes.to_bytes()
  bytes[1] = b'\x02'
  // now content is [0, 2, 2]
}

@peter-jerry-ye
Copy link
Collaborator

peter-jerry-ye commented Feb 10, 2025

Apart from that, Bytes is more like FixedArray[Byte] instead of Array[Byte] as Array[Byte] is actually an object that has

  • a larger FixedArray[Byte] than it is used
  • extra properties to track its current usage

So Array[Byte] is analogous to Buffer, while the latter has more specific operations.

@zxch3n
Copy link
Author

zxch3n commented Feb 10, 2025

Got it, thanks. I opened this issue because I think it should also be included in the docs (in the website and the code)

@peter-jerry-ye peter-jerry-ye added question Further information is requested documentation Improvements or additions to documentation labels Feb 10, 2025
@zxch3n
Copy link
Author

zxch3n commented Feb 10, 2025

BTW, could there be an API like Array::take_bytes() -> Bytes that clears the original Array, transfers the original content to Bytes, and thus implements zero cost conversion?

@peter-jerry-ye
Copy link
Collaborator

Do you have a concrete use case? I think it's possible for Buffer to implement it as long as the reserved size is exactly what you want, but I can not guarantee. For FixedArray[Byte], it is possible for certain backends as long as we are using reference counting so we can check if it is zero.

@zxch3n
Copy link
Author

zxch3n commented Feb 10, 2025

I think it would be great if there were a preferred way to handle Bytes. If the conversion is free, a function can always return a Array[Byte] for maximum compatibility.

@peter-jerry-ye
Copy link
Collaborator

Why not use a BytesView then?

@zxch3n
Copy link
Author

zxch3n commented Feb 11, 2025

When serializing an object, we may not know the size of the serialized data in advance. So we need to initialize it as Array[Byte] first, right? Also, the caller of the function may want to extend the array with other data. So Array[Byte] may be the most flexible return type if we can convert it into Bytes/BytesView with zero cost.

@peter-jerry-ye
Copy link
Collaborator

If you are trying to serializing data that you don't know the size in advance, you will definitely resize the buffer and introduce copying, and the final result can hardly be the exact size, which will introduce another copy. So I don't see how the 'zero cost' can be benefitial

peter-jerry-ye added a commit that referenced this issue Feb 11, 2025
@zxch3n
Copy link
Author

zxch3n commented Feb 11, 2025

It's a good point. But we usually don't need the capacity and length to be the same, right? My thought is if there is an ideal way to deal with bytes, there can be a convention so that people can share code more easily in the future.

BTW, will Bytes and Array[Byte] be compiled to Uint8Array when targeting JS? If it's number[], they will still be stored as 32-bit numbers in JS runtime, right?

@peter-jerry-ye
Copy link
Collaborator

I would suggest sharing with BytesView.

As of the ABI, I don't think it's stable yet (i.e. we won't make a commitment yet). I think the primitives are compiled to ArrayBuffer's @hackwaly is that the case?

@hackwaly
Copy link

hackwaly commented Feb 11, 2025

We compiles Bytes / FixedArray[Byte] to Uint8Array. But due to implementation complexity, the backing buffer of Array[Byte] MAY be not Uint8Array. Some explanation here: In JavaScript Uint8Array has different prototype with Array.

I think you'd better to build a Array like growable container based on FixedArray[Byte] and using it to working on bytes. As we won't have it in near future.

@zxch3n
Copy link
Author

zxch3n commented Feb 11, 2025

Ah. I see. Thanks

@hackwaly
Copy link

Sorry. There's core/buffer I forgot.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation question Further information is requested
Projects
None yet
Development

No branches or pull requests

3 participants