I'm working on loading PNG files. I know there are existing libraries, but I'm doing this for learning purposes. Previously, I was using LodePNG, which is a great library that performs really well.
I have a large PNG, 2048x2048 pixels with 8 bits of depth. I load it ten times with my code, and average out the time it takes (measured with std::chrono). I do the same with LodePNG. LodePNG is built in the solution so it's using the same compiler flags as my own code.
Initially I found that my library would take ~8000ms on average to load the image whereas LodePNG takes on average ~800ms. 10 times longer!
Using this technique I have managed to reduce my execution time down to ~3100ms. This was through a series of improvements:
std::uint_fast32_tsort of types in place of
std::uint32_twhere it made sense
- Refactoring some parts of code several times
- Replacing some
std::vectors where I could (I naively used maps when it wasn't required)
- Enabled Link-Time Optimisation (which didn't help LodePNG speed but shaved 100ms off mine)
However, I've found now that the random interrupting and checking the backtrace in GDB is revealing the same bits of code over and over again:
- Calls to
- Calls to the creation of
std::vectors (I'm using a custom memory allocator that performs better, it's also being used for pointer creation)
Which aren't things I can improve upon. LodePNG is mostly C-like code, it doesn't use any Standard Library headers. But, I always read that using these libraries shouldn't be any slower... but well here I am.
My question is, what else can I do to identify hot-spots and fix them? Any techniques that would be appropriate? Ideally they would work on Windows.
I'm using GCC 10.2 through MingW64 in MSYS2.