-
Notifications
You must be signed in to change notification settings - Fork 178
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
Remove some serializations in MapView
.
#3036
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changes seem rather arbitrary - I don't see any explanation why we're doing that.
Serializing data and deserializing is a very inefficient method. Replacing by Clone is much better in terms of speed. |
I'm not sure about this: It considerably complicates the public API, and in almost all cases it's the values we want, not the bytes. |
linera-views/src/views/map_view.rs
Outdated
@@ -1279,7 +1367,7 @@ where | |||
{ | |||
let prefix = Vec::new(); | |||
self.map | |||
.for_each_key_value( | |||
.for_each_key_value_or_bytes( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Most of these can be just for_each_key_value
, so we don't need the to_value
call below.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, thank you.
linera-views/src/views/map_view.rs
Outdated
@@ -776,7 +776,7 @@ where | |||
/// assert_eq!(count, 1); | |||
/// # }) | |||
/// ``` | |||
pub(crate) async fn for_each_key_value_or_bytes<'a, F>( | |||
pub async fn for_each_key_value_or_bytes<'a, F>( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So you want to make it public after all? I'd keep this and the ValueOrBytes
type private.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes please
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, changed.
mut f: F, | ||
prefix: Vec<u8>, | ||
) -> Result<(), ViewError> | ||
where | ||
F: FnMut(&[u8], &[u8]) -> Result<bool, ViewError> + Send, | ||
F: FnMut(&[u8], ValueOrBytes<'a, V>) -> Result<bool, ViewError> + Send, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function is public API. Why would a user want to see the bytes?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, wrong move. I wanted the test functions to be running, but that was a wrong idea.
I personally don't like the added code complexity with no performance gains to show for. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
back to your queue for the questions
|index, value| { | ||
count += 1; | ||
hasher.update_with_bytes(index)?; | ||
hasher.update_with_bytes(value)?; | ||
let bytes = value.to_bytes()?; | ||
hasher.update_with_bytes(&bytes)?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok now I understand the motivation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you.
T: Clone + DeserializeOwned, | ||
{ | ||
/// Convert to a value. | ||
pub fn to_value(self) -> Result<T, ViewError> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could also use to_cow
to avoid a clone
@@ -838,11 +920,12 @@ where | |||
let mut hasher = sha3::Sha3_256::default(); | |||
let mut count = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should write 0u32
here. Otherwise the hashing scheme is not well defined
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh yes, and this impacts other containers, and it makes the change TestNet/DevNet breaking.
@@ -67,6 +67,40 @@ pub struct ByteMapView<C, V> { | |||
updates: BTreeMap<Vec<u8>, Update<V>>, | |||
} | |||
|
|||
/// Whether we have a value or its serialization. | |||
pub enum ValueOrBytes<'a, T> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still not private
Motivation
The performance of the
MapView
has recently emerged as a subject of concern. While the use of async Iterators is under discussion, it is clear that there are other issues.Proposal
The following was done:
ValueOrBytes
was introduced to represent the fact that in some cases we have the values and in some other cases its serialization.for_each_key_value_while
no longer serializes the values; it just creates aValueOrBytes::Value
.iterator()
is replaced by ainto_iterator_owned()
since this avoids a.to_vec()
in the construction of theValueOrBytes::Bytes
. Note that we cannot have aBytes(&
a [u8])since indeed the scope of
f` is larger than the one in which the key values are created.Clone
traits have to be added. But this should be viewed as a gain since before we were serializing and then deserializing, i.e. a very expensive clone.index_values
were needlessly complex. They are replaced by simpler code.Possible criticism:
for_each_key_value
andfor_each_key_value_while
are kept even if their use is complex. This is not an issue as those functions are not used outside of thelinera-views
code. They could be made private.Test Plan
The CI should do the job.
Release Plan
The PR could be deployed on TestNet / DevNet as desired.
Links
None.