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

Try to enhance performance of FNT(257) #264

Merged
merged 6 commits into from
Mar 21, 2019
Merged

Try to enhance performance of FNT(257) #264

merged 6 commits into from
Mar 21, 2019

Conversation

lamphamsy
Copy link
Contributor

  • 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 encoding
    The use of two vectors improves 1.5-2x on encoding speeds. And a significant enhancement is observed for decoding.

@vrancurel vrancurel added the Release 0.1 Initial Release label Dec 19, 2018
@lamphamsy lamphamsy force-pushed the eh/props branch 3 times, most recently from 4233ae6 to c4e704a Compare February 8, 2019 13:13
src/property.cpp Outdated Show resolved Hide resolved
src/property.cpp Outdated Show resolved Hide resolved
src/property.h Outdated Show resolved Hide resolved
src/property.h Outdated Show resolved Hide resolved
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++) {
Copy link
Contributor

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?

Copy link
Contributor Author

@lamphamsy lamphamsy Feb 13, 2019

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
Copy link
Contributor

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:

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 toProperties`.
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();
    }

Copy link
Contributor Author

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

src/fec_context.h Show resolved Hide resolved
src/property.h Outdated Show resolved Hide resolved
src/property.h Outdated Show resolved Hide resolved
src/property.h Outdated Show resolved Hide resolved
Copy link
Contributor Author

@lamphamsy lamphamsy left a 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/fec_context.h Show resolved Hide resolved
src/property.cpp Outdated Show resolved Hide resolved
src/property.h Outdated Show resolved Hide resolved
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));
Copy link
Contributor Author

@lamphamsy lamphamsy Feb 13, 2019

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++) {
Copy link
Contributor Author

@lamphamsy lamphamsy Feb 13, 2019

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 Show resolved Hide resolved
src/property.h Outdated
@@ -141,6 +142,63 @@ class FntProperties : public Properties {
public:
};

/** Iterator on Properties
Copy link
Contributor Author

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

src/property.h Outdated Show resolved Hide resolved
src/property.h Outdated Show resolved Hide resolved
src/property.h Outdated Show resolved Hide resolved
@lamphamsy lamphamsy force-pushed the eh/props branch 2 times, most recently from ccf58c0 to 3da1a26 Compare February 20, 2019 13:34
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`.
@lamphamsy lamphamsy merged commit 6b465d4 into master Mar 21, 2019
@lamphamsy lamphamsy deleted the eh/props branch March 21, 2019 15:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Release 0.1 Initial Release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants