-
Notifications
You must be signed in to change notification settings - Fork 6
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
Try to enhance performance of FNT(257) #264
Conversation
4233ae6
to
c4e704a
Compare
src/property.h
Outdated
for (auto& kv : props) { | ||
dwords[i++] = htonl(static_cast<uint32_t>(kv.first)); | ||
for (auto const& key : keys) { | ||
dwords[i++] = htonl(static_cast<uint32_t>(key)); | ||
} | ||
dwords[1] = htonl(i - 2); | ||
for (; i < n_dwords; i++) { |
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.
again not your code, but 0 has the same representation in little endian and big endian, so why not using a fill
of fill_n
instead of a manual loop here?
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.
okay, I will update it
- use
fill
src/property.h
Outdated
@@ -141,6 +142,63 @@ class FntProperties : public Properties { | |||
public: | |||
}; | |||
|
|||
/** Iterator on Properties |
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.
Good idea to add an iterator to Properties
🙂
But that's not how you implement an iterator in C++.
See:
- https://stackoverflow.com/questions/7758580/writing-your-own-stl-container/7759622#7759622 (an example)
- http://www.cplusplus.com/reference/iterator/ForwardIterator/ (to see the expected interface)
- https://www.fluentcpp.com/2018/05/08/std-iterator-deprecated/
Note that they're usually implemented as a nested class (nested in the container).
In think in our use case, implementing a forward iterator should be enough.
Note that by using a std::pair
as value_type
, you can even keep the code that was used with unordered_map
(with first
and second
).
And once you have your iterator class, you should add the begin and
endmethods to
Properties`.
Once you have those two, it's very easy to provide the whole interface.
iterator begin() noexcept
{
[…]
}
const_iterator begin() const noexcept
{
[…]
}
iterator end() noexcept
{
[…]
}
const_iterator end() const noexcept
{
[…]
}
const_iterator cbegin() const noexcept
{
return begin();
}
const_iterator cend() const noexcept
{
return end();
}
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, I will try to improve the iterator.
I checked that unordered_map
or map
don't give good perf for both of encoding (insert) and decoding (access). Vector is a better approach IMHO.
We can find a comparison between them, e.g. http://john-ahlgren.blogspot.com/2013/10/stl-container-performance.html
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.
Thanks so much for your reviews
src/property.h
Outdated
for (auto& kv : props) { | ||
dwords[i++] = htonl(static_cast<uint32_t>(kv.first)); | ||
for (auto const& key : keys) { | ||
dwords[i++] = htonl(static_cast<uint32_t>(key)); |
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, we should have a better solution for fnt_serialize
. Could you create an issue for it?
- use
narrow_cast
src/property.h
Outdated
for (auto& kv : props) { | ||
dwords[i++] = htonl(static_cast<uint32_t>(kv.first)); | ||
for (auto const& key : keys) { | ||
dwords[i++] = htonl(static_cast<uint32_t>(key)); | ||
} | ||
dwords[1] = htonl(i - 2); | ||
for (; i < n_dwords; i++) { |
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.
okay, I will update it
- use
fill
src/property.h
Outdated
@@ -141,6 +142,63 @@ class FntProperties : public Properties { | |||
public: | |||
}; | |||
|
|||
/** Iterator on Properties |
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, I will try to improve the iterator.
I checked that unordered_map
or map
don't give good perf for both of encoding (insert) and decoding (access). Vector is a better approach IMHO.
We can find a comparison between them, e.g. http://john-ahlgren.blogspot.com/2013/10/stl-container-performance.html
ccf58c0
to
3da1a26
Compare
We use std::vector to store pairs of location and marker. It gives better performance compared to map or unordered_map for our operations: addition & accessing. Util functions are added: - location(i): get location of the ith element - marker(i): get marker of the ith element - is_marked(i, loc): check if location of the ith element == loc - in_range(i, min, max): check if location of the ith element is within the range [min, max) Note, in these util functions, we assume that stored elements are sorted in ascending order of location.
Each property will be sort Add vector of indices that stores index of the accessing currently element of Property
- As `props_indices` in `DecodeContext` will be updated during decoding, we remove `const` keyword in declarations of `DecodeContext` and `Properties` - We note that the locations are retrieved in the ascending order according to the decoding process. Hence we implemented util functions in Properties to retrieve location of symbols whose value = `q-1`.
- As `props_indices` in `DecodeContext` will be updated during decoding, we remove `const` keyword in declarations of `DecodeContext` and `Properties` - Use util functions in Properties to retrieve location of symbols whose value = `q-1`.
It focuses on improving performance of FNT(257)
Use two vectors instead of unordered_map: one vector for locations, the other for marked values.
I tried to use
reserve()
for unordered_map`, it improves about 10% for encodingThe use of two vectors improves 1.5-2x on encoding speeds. And a significant enhancement is observed for decoding.