Search code examples
ccompilationprologelfswi-prolog

What is the benefit of using SWI-Prolog's qsave_program to generate a binary?


I've been playing around with Prolog's qsave_program functionality. I am on the market for something that would speed up my Prolog code, or possibly allow for integration with C/C++.

I used the following command to produce a binary from my SWI-prolog program:

swipl -o prog -c prog.pl --stand_alone=true

Under the hood this calls qsave_program.

After inspecting the binary file, it was in the expected ELF format, so then I tried running it.

However, when I run this compiled ./prog program on the terminal, using strace, the output logs indicate that the executable is indeed pulling in swi-prolog libraries from all over the place. This indicates to me that there aren't as many performance benefits in using the compiled code versus using a plain old SWI-prolog executable via a hashbang script.

Am I missing something? Is there a way to force the compilation process to package in the necessary libraries (for greater portability), and does this entire process involve any optimisation of the Prolog code, or is it just as well to avoid compilation here?


Solution

  • From the documentation:

    Another solution is to use saved states, the main topic of this chapter, together with the installed development system and disable autoloading requirements into the state using --no-autoload or the autoload(false) option of qsave_program/2. This allows creating the application as a single file, while avoiding the need to ensure that the state is self-contained. For large programs this technique typically reduces startup time by an order of magnitude. This mechanism is particularly suitable for in-house and cloud deployment. It provides some protection against inspecting the source. See section 14.6 for details.

    So, easier distribution (fewer files to worry about) and faster startup time (SWI doesn't need to read the source code and compile it to its internal format each time). Sounds like it's possible to build an image that directly includes used libraries and the SWI VM too so it's truly a single bundle:

    The final solution is to make sure all required resources are present in the saved state. In this case the state may be added to the emulator and the application consists of the emulator with state and the shared objects/DLLs required to make the emulator work. If the emulator can be statically linked for the target platform this creates a single file executable that does not require SWI-Prolog installed on the target computer.

    I think the stand_alone(true) option is what you need for that.