xiaozhuai / imageinfo

Free Palestine🇵🇸🇵🇸🇵🇸Cross platform super fast single header c++ library to get image size and format without loading/decoding. Support avif, bmp, cur, dds, gif, hdr (pic), heic (heif), icns, ico, j2k, jp2, jpeg (jpg), jpx, ktx, png, psd, qoi, tga, tiff (tif), webp ...
MIT License
106 stars 26 forks source link

Optimize parser #9

Closed Mis1eader-dev closed 6 months ago

Mis1eader-dev commented 6 months ago

This PR makes the lookup of parsers and checking already tried parsers faster and more efficient, by avoiding heap allocation completely.

Instead it uses bit manipulations to check if a certain parser has already been executed. This reduces the space that was used previously by the dl vector, dm unordered_map, and tried unordered_set. Now the parsers are in a constexpr C array, and the tried unordered_set has been turned into a 3 byte array containing byte flags. As for lookup, it is significantly faster than using the unordered_map, as all we do now for lookup is a division by 8, a multiplication by 8, a subtraction, and a left bit shift.

I have added a static_assert for the parsers as well, to make sure we don't push into master without adding new parsers to the dl array.

xiaozhuai commented 6 months ago

@Mis1eader-dev Thanks for the pr. I'd suggest you to install clang-format-17 follow this document https://apt.llvm.org/ and format code before commit. Otherwise, the CI wouldn't pass.

xiaozhuai commented 6 months ago

@Mis1eader-dev I'm afraid we cannot change tried to bit flags, Some formats use the same detector, such as:

Mis1eader-dev commented 6 months ago

@Mis1eader-dev Thanks for the pr. I'd suggest you to install clang-format-17 follow this document https://apt.llvm.org/ and format code before commit. Otherwise, the CI wouldn't pass.

Ok I'll try to have a go at it when I'm back home

@Mis1eader-dev I'm afraid we cannot change tried to bit flags, Some formats use the same detector, such as:

  • avif heic
  • ico cur

I didn't realize that was the case, I'll think of a more elaborate solution

Mis1eader-dev commented 6 months ago

@xiaozhuai I am unable to obtain clang-format-17 on Ubuntu, the last stable version I could retrieve is clang-format-15

Mis1eader-dev commented 6 months ago

I have some more optimizations in mind, and have to fix a small issue before merge.

xiaozhuai commented 6 months ago

I am unable to obtain clang-format-17 on Ubuntu

What's the version of your ubuntu?

Mis1eader-dev commented 6 months ago

Ubuntu 22.04 LTS

xiaozhuai commented 6 months ago

Ubuntu 22.04 LTS

Try this : )

wget -qO- https://apt.llvm.org/llvm-snapshot.gpg.key | sudo tee /etc/apt/trusted.gpg.d/apt.llvm.org.asc
echo "deb https://apt.llvm.org/jammy/ llvm-toolchain-jammy-17 main" | sudo tee -a /etc/apt/sources.list
echo "deb-src https://apt.llvm.org/jammy/ llvm-toolchain-jammy-17 main" | sudo tee -a /etc/apt/sources.list
sudo apt-get update
sudo apt-get install clang-format-17

After that, exec

clang-format-17 -i -verbose include/imageinfo.hpp
xiaozhuai commented 6 months ago

@Mis1eader-dev Inspired by this PR, I made some changes. Any suggestions?

xiaozhuai commented 6 months ago

The last thing is check format order in dl and Format enum.

// for i = 0..countof(dl)
static_assert(dl[i].format == (Format)(i + 1), "Format must keep in order");
xiaozhuai commented 6 months ago
template <size_t N>
struct check_format_order_ {
    template <int I>
    constexpr static bool check(const DetectorInfo (&dl)[N]) {
        return dl[I].format == (Format)(I + 1) && check<I - 1>(dl);
    }

    template <>
    constexpr static bool check<0>(const DetectorInfo (&dl)[N]) {
        return dl[0].format == (Format)(0 + 1);
    }
};

template <size_t N>
constexpr bool check_format_order(const DetectorInfo (&dl)[N]) {
    return check_format_order_<N>::template check<N - 1>(dl);
}

static_assert(check_format_order(dl), "Format order is incorrect");

These code not working on ubuntu with g++. See https://github.com/xiaozhuai/imageinfo/actions/runs/7969028503/job/21754194096?pr=9 Metaprogramming in c++ is always painful : (

xiaozhuai commented 6 months ago

This pr is ready to merge now. @Mis1eader-dev Would you please review it again and make some suggestions?

xiaozhuai commented 6 months ago

@Mis1eader-dev One more thing.

I would like to invite you to collaborate with me on this project. Your expertise and contributions would be incredibly valuable to the success of this project. If you are interested, please let me know, and I will send you an invitation to join as a collaborator : )

Mis1eader-dev commented 6 months ago

This pr is ready to merge now. @Mis1eader-dev Would you please review it again and make some suggestions?

I will review it if I had time later on today

@Mis1eader-dev One more thing.

I would like to invite you to collaborate with me on this project. Your expertise and contributions would be incredibly valuable to the success of this project. If you are interested, please let me know, and I will send you an invitation to join as a collaborator : )

Sure thing, I would like to contribute to the project

xiaozhuai commented 6 months ago

Please visit https://github.com/xiaozhuai/imageinfo/invitations to join as a collaborator.

Mis1eader-dev commented 6 months ago

It's good to merge

xiaozhuai commented 6 months ago

Merged!