Skip to main content

Performance

Most heavy duty operations are done using compiled native executables, IPP is the organisation glue that holds everything together.

Implementation decisions

Excellent performance is one of the main goals of IPP. To achieve this, the project has undertaken careful consideration regarding the choice of compiled/runtime languages and third-party libraries.

All of the orchestration logic, such as deciding which pipes to execute, is written in JavaScript (technically TypeScript) which runs on Node.js, using the same V8 runtime as the Chrome and Edge browsers. Despite its excellent single-threaded performance, being able to hold its own even against some of the best, it is still not ideal for computationally and memory intensive tasks.

This is why more computationally intensive operations are done using bundled compiled binaries. For example, image resize operations are done using libvips, an amazingly efficient and fast image manipulation library.

Another factor in the decision to use Node.js and its tight integration with npm was the ability to universally bundle compiled binaries, whether they are written in C++ or in Go, with the use of a lightweight JavaScript wrapper.

Future improvements

At the moment, pipes use pre-compiled binaries for the three major operating systems (Windows, macOS and Linux).

In the future, pipes may bundle a universal WebAssembly module that would work cross-platform, and even in the browser. The technology is not fully matured, however, and would require a certain amount of work to compile C++/Go source into a WebAssembly target.

Optimising performance

The biggest factor that determines performance is the choice of pipes in your pipeline. One of IPP's directives is speed, by using native binaries from performant image libraries. Speed is therefore not determined by the compiled language used, but rather by the nature of the pipe.

Resizing images is relatively cheap, however dedicated compression libraries (such as those provided by @ipp/compress) whilst providing superior image quality must sacrifice in speed.

Another example of an computationally intensive task is generating SVG placeholders using the @ipp/primitive pipe. The algorithm generates an arbitrary (based on the given options) number of test images in order to determine the best fit for the original image.

If performance is a major concern for your implementation, it may be best to stick to "cheap" pipes such as resizing and converting.

PipeSpeedLanguageDescription
resize🟢CResizes images using the libvips library
convert🟢CConverts image formats using the libvips library
compress🟠C, C++Compresses images using various implementations
potrace🟠JavaScriptGenerates traced SVG placeholders
primitive🔴GoGenerates primitive SVG placeholders
Approximated relative pipe speeds, from fast to slow: 🟢🟠🔴