# Curious: How does Prolog "Byte code" compare to .NET IL (and some thoughts about enterprise ready systems)

**URL:** <https://swi-prolog.discourse.group/t/curious-how-does-prolog-byte-code-compare-to-net-il-and-some-thoughts-about-enterprise-ready-systems/1101>\
**Category:** Help!\
**Created:** [August 21, 2019, 3:27pm UTC](https://swi-prolog.discourse.group/t/curious-how-does-prolog-byte-code-compare-to-net-il-and-some-thoughts-about-enterprise-ready-systems/1101 "2019-08-21T15:27:02Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![grossdan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/grossdan/32/23_2.png) [@grossdan](https://swi-prolog.discourse.group/u/grossdan)\
**Post date:** [August 21, 2019, 3:27pm UTC](https://swi-prolog.discourse.group/t/curious-how-does-prolog-byte-code-compare-to-net-il-and-some-thoughts-about-enterprise-ready-systems/1101/1 "2019-08-21T15:27:02Z")

</div>

Hi,

I happened to look at some C# code today disassembled into .NET IL “byte code” – which reminded me that SWI-Prolog also has its byte code and (WAM) VM.

I am curious – how do these compare in practice in terms of performance. Question is also applicable to Java byte code and VM. I guess all these are highly optimized but, then again, they are VMs.

The reason i was asked is whether my code could be made enterprise ready – with a hint that a rewrite with Java EE would be appropriate …

In terms of enterprise architecture – perhaps its sufficient to work with parallel engines each running in an own thread – although some writes to a shared Prolog store would be needed.

any thoughts are much appreciated,

Dan

---

<div class="post-metadata">

**Author:** ![EricGT](https://avatars.discourse-cdn.com/v4/letter/e/f1d935/32.png) [@EricGT](https://swi-prolog.discourse.group/u/EricGT)\
**Post date:** [August 21, 2019, 3:29pm UTC](https://swi-prolog.discourse.group/t/curious-how-does-prolog-byte-code-compare-to-net-il-and-some-thoughts-about-enterprise-ready-systems/1101/2 "2019-08-21T15:29:48Z")

</div>

> [@grossdan](#):
>
> SWI-Prolog also has its byte code and (WAM) VM.

AFAIK SWI-Prolog is implemented with C, there is no IL, it does not use WAM.

---

<div class="post-metadata">

**Author:** ![grossdan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/grossdan/32/23_2.png) [@grossdan](https://swi-prolog.discourse.group/u/grossdan)\
**Post date:** [August 21, 2019, 3:31pm UTC](https://swi-prolog.discourse.group/t/curious-how-does-prolog-byte-code-compare-to-net-il-and-some-thoughts-about-enterprise-ready-systems/1101/3 "2019-08-21T15:31:23Z")

</div>

Thanks.

I mean, swi-prolog programs are translated into byte code and executed through a WAM VM

Dan

---

<div class="post-metadata">

**Author:** ![EricGT](https://avatars.discourse-cdn.com/v4/letter/e/f1d935/32.png) [@EricGT](https://swi-prolog.discourse.group/u/EricGT)\
**Post date:** [August 21, 2019, 3:34pm UTC](https://swi-prolog.discourse.group/t/curious-how-does-prolog-byte-code-compare-to-net-il-and-some-thoughts-about-enterprise-ready-systems/1101/4 "2019-08-21T15:34:16Z")

</div>

I started searching the [source](https://github.com/SWI-Prolog/swipl-devel/tree/master/src) at GitHub and found [pl-wam.c](https://github.com/SWI-Prolog/swipl-devel/blob/ea88f5f4b6bfe3ad87bbc86a930125fdf2b18842/src/pl-wam.c) so now I have to question my own reply.

---

<div class="post-metadata">

**Author:** ![grossdan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/grossdan/32/23_2.png) [@grossdan](https://swi-prolog.discourse.group/u/grossdan)\
**Post date:** [August 21, 2019, 3:37pm UTC](https://swi-prolog.discourse.group/t/curious-how-does-prolog-byte-code-compare-to-net-il-and-some-thoughts-about-enterprise-ready-systems/1101/5 "2019-08-21T15:37:28Z")

</div>

There is also the command:

vm\_list(Predicate\_name)

---

<div class="post-metadata">

**Author:** ![EricGT](https://avatars.discourse-cdn.com/v4/letter/e/f1d935/32.png) [@EricGT](https://swi-prolog.discourse.group/u/EricGT)\
**Post date:** [August 21, 2019, 3:50pm UTC](https://swi-prolog.discourse.group/t/curious-how-does-prolog-byte-code-compare-to-net-il-and-some-thoughts-about-enterprise-ready-systems/1101/6 "2019-08-21T15:50:47Z")

</div>

The keyword I use to search the SWI-Prolog source code for where the Prolog predicates are implemented in C is [PRED\_IMPL](https://github.com/SWI-Prolog/swipl-devel/search?q=PRED_IMPL&unscoped_q=PRED_IMPL)

The way I think of the code is that what can be done with Prolog is done in Prolog, the low level actions such as [unification](https://github.com/SWI-Prolog/swipl-devel/blob/9ed270918b425d123be31c323366dc5e871f52cc/src/pl-prims.c#L207-L396) are done in C. Then if a predicate needs to be faster it is done with calls straight into C.

Sometimes, as Jan notes, the code is so tricky that it is better to implement in C than Prolog.

That is why I say AFAIK it does not use a Virtual Machine such as [WAM](https://en.wikipedia.org/wiki/Warren_Abstract_Machine) or an Intermediate Language such as JVM or CIL.

I know Jan will correct me if this is wrong and then I will have learned something.

Related questions:

[How can a foreign language predicate also be a built-in predicate?](https://swi-prolog.discourse.group/t/how-can-a-foreign-language-predicate-also-be-a-built-in-predicate/961)  
[“decompiled prolog”](https://swi-prolog.discourse.group/t/decompiled-prolog/729)

[Efficiency of Prolog](https://www.metalevel.at/prolog/efficiency)

* * *

> **Personal Notes**
>
> [vm\_list/1](https://www.swi-prolog.org/pldoc/man?predicate=vm_list/1).
> 
> ```prolog
> ?- vm_list(append).
> ========================================================================
> append/2
> ========================================================================
> 0 s_trustme(clause(638140))
> ----------------------------------------
> clause 1 (<clause>(000001707FC6F2F0)):
> ----------------------------------------
> 0 i_enter
> 1 b_atom(list)
> 3 b_var0
> 4 i_call(error:must_be/2)
> 6 b_var0
> 7 b_var1
> 8 i_depart(lists:append_/2)
> 10 i_exit
> ========================================================================
> append/3
> ========================================================================
> 0 s_list(clause(735160),clause(641508))
> ----------------------------------------
> clause 1 (<clause>(000001707FCCDEE0)):
> ----------------------------------------
> 0 h_nil
> 1 h_void
> 2 h_var(1)
> 4 i_exitfact
> ----------------------------------------
> clause 2 (<clause>(000001707FC72790)):
> ----------------------------------------
> 0 h_list_ff(3,4)
> 3 h_void
> 4 h_list
> 5 h_var(3)
> 7 h_firstvar(5)
> 9 h_pop
> 10 i_enter
> 11 b_var(4)
> 13 b_var1
> 14 b_var(5)
> 16 i_depart(lists:append/3)
> 18 i_exit
> ========================================================================
> append/1
> ========================================================================
> 0 i_fopen
> 1 i_fcalldetva(-4611686413639185926)
> 3 i_fexitdet
> true.
> 
> ```
> 
> Source code:
> 
> [pl-wam.c](https://github.com/SWI-Prolog/swipl-devel/blob/ea88f5f4b6bfe3ad87bbc86a930125fdf2b18842/src/pl-wam.c)  
> [pl-vmi.c](https://github.com/SWI-Prolog/swipl-devel/blob/ea88f5f4b6bfe3ad87bbc86a930125fdf2b18842/src/pl-vmi.c)  
> [pl-supervisor.c](https://github.com/SWI-Prolog/swipl-devel/blob/ea88f5f4b6bfe3ad87bbc86a930125fdf2b18842/src/pl-supervisor.c)  
> [pl-comp.c](https://github.com/SWI-Prolog/swipl-devel/blob/master/src/pl-comp.c)  
> [pl-export](https://github.com/SWI-Prolog/swipl-devel/blob/master/src/pl-export)
> 
> From: pl-vmi.c  
> Virtual machine instruction names. Prefixes:
> 
> | I\_ | General instructions |
> | B\_ | Body specific version |
> | H\_ | Head specific version |
> | A\_ | Arithmetic compilation specific |
> | C\_ | Control (compilation of ;/2, etc.) |
> | S\_ | Supervisor instructions. See pl-supervisor.c |
> 
> References:
> 
> [Logic Programming Implementation - Part I: The WAM](https://www.it.uu.se/edu/course/homepage/logpro/ht04/LP_Impl.pdf)  
> [Limits on memory areas](https://www.swi-prolog.org/pldoc/man?section=memlimit) - Notes trail stack which is also part of WAM.  
> [Warren’s Abstract Machine - A Tutorial Reconstruction](http://wambook.sourceforge.net/wam-slides.pdf) - List the basic instructions of WAM such as `put_structure`, `set variable`, `unify_value`, `unify_variable`.  
> [An Abstract Prolog Instruction Set](http://www.ai.sri.com/pubs/files/641.pdf)
> 
> From `pl-comp.c`
> 
> > This module (pl-comp.c) forms together with the module ‘pl-wam.c’ the complete  
> > kernel of SWI-Prolog.
> 
> Excerpts from: \_ **Bowen _et al._ , 1983** D. L. Bowen, L. M. Byrd, and WF. Clocksin. A portable Prolog compiler.
> 
> > We have opted for the structure-copying method of [Mellish 80] and [Bryunooghe 80], rather than the structure-sharing [Warren 77].
> 
> > Our storage management strategy is basically that of [Warren 77], i.e. there is a heap containing the program, a “local” stack for control information and variable bindings, a “global” stack for structures, and a "trail stack which keeps track of when variables are bound so that they can be reset to “uninstantiated” at the appropriate time on backtracking. One change is that a reference count is maintained for each clause so that pointers to clauses can safely be included in asserted terms.
> 
> > As our run-time system is based on previously published work [Warren 77] [warren 80]
> 
> * * *
> 
> EDIT: After responses ([1](https://swi-prolog.discourse.group/t/curious-how-does-prolog-byte-code-compare-to-net-il-and-some-thoughts-about-enterprise-ready-systems/1101/8)) ([2](https://swi-prolog.discourse.group/t/curious-how-does-prolog-byte-code-compare-to-net-il-and-some-thoughts-about-enterprise-ready-systems/1101/9)) by Jan W.
> 
> References:
> 
> [SWI-Prolog Implementation history](https://www.swi-prolog.org/pldoc/man?section=implhistory)
> 
> **Bowen _et al._ , 1983**  
> D. L. Bowen, L. M. Byrd, and WF. Clocksin. [A portable Prolog compiler](https://www.researchgate.net/publication/273888197_A_portable_Prolog_compiler). In L. M. Pereira, editor, _Proceedings of the Logic Programming Workshop 1983_ , Lisabon, Portugal, 1983. Universidade nova de Lisboa. - Explains low level concepts such as control instructions: `enter`, `call`, and `exit`.
> 
> **Neumerkel, 1993**  
> Ulrich Neumerkel. The binary WAM, a simplified Prolog engine. Technical report, Technische Universität Wien , 1993 - [The binary WAM, a simplified Prolog engine](http://www.complang.tuwien.ac.at/ulrich/papers/PDF/binwam-nov93.pdf) - Notes design concepts of Prolog abstract machines (as opposed to virtual machine VM) at time, including ZIP.
> 
> EDIT:
> 
> This reminds me of [minProlog](https://github.com/andrejbauer/plzoo/tree/master/src/miniprolog) and specifically the execution engine ([solve.ml](https://github.com/andrejbauer/plzoo/blob/master/src/miniprolog/solve.ml))  
> This also reminds me of the MIT open couseware lecture of [advanced data structures](https://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-851-advanced-data-structures-spring-2012/) ([videos](https://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-851-advanced-data-structures-spring-2012/lecture-videos/)) . There was one in particular but I can’t remember the exact one.

---

<div class="post-metadata">

**Author:** ![EricGT](https://avatars.discourse-cdn.com/v4/letter/e/f1d935/32.png) [@EricGT](https://swi-prolog.discourse.group/u/EricGT)\
**Post date:** [August 21, 2019, 4:28pm UTC](https://swi-prolog.discourse.group/t/curious-how-does-prolog-byte-code-compare-to-net-il-and-some-thoughts-about-enterprise-ready-systems/1101/7 "2019-08-21T16:28:01Z")

</div>

What confuses me is that if I use vm\_list/1 on unification (=)

```prolog
?- vm_list(=).
========================================================================
=/2
========================================================================
   0 i_fopen
   1 i_fcalldetva(4611685623215523968)
   3 i_fexitdet
true.

```

and then if I search the C [unification](https://github.com/SWI-Prolog/swipl-devel/blob/9ed270918b425d123be31c323366dc5e871f52cc/src/pl-prims.c#L207-L396) code for `i_fcalldetva`, `i_fcalldetva` is not found.

So what is the relationship between [vm\_list/1](https://www.swi-prolog.org/pldoc/man?predicate=vm_list/1), the source files [pl-wam.c](https://github.com/SWI-Prolog/swipl-devel/blob/ea88f5f4b6bfe3ad87bbc86a930125fdf2b18842/src/pl-wam.c)  
[pl-vmi.c](https://github.com/SWI-Prolog/swipl-devel/blob/bf5ff3dae48f263ddceb487899c9ba0b3874c6c0/src/pl-vmi.c) and the implementation of the predicates using [PRED\_IMPL](https://github.com/SWI-Prolog/swipl-devel/search?q=PRED_IMPL&unscoped_q=PRED_IMPL)?

When I look at the instructions for the WAM, e.g. `unify_value` I would expect to see them in the result from `vm_list(=)`. So what is vm\_list/1 really returning?

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [August 22, 2019, 9:18am UTC](https://swi-prolog.discourse.group/t/curious-how-does-prolog-byte-code-compare-to-net-il-and-some-thoughts-about-enterprise-ready-systems/1101/8 "2019-08-22T09:18:56Z")

</div>

> [@EricGT](#):
>
> The way I think of the code is that what can be done with Prolog is done in Prolog, the low level actions such as [unification](https://github.com/SWI-Prolog/swipl-devel/blob/9ed270918b425d123be31c323366dc5e871f52cc/src/pl-prims.c#L207-L396) are done in C. Then if a predicate needs to be faster it is done with calls straight into C.
> 
> Sometimes, as Jan notes, the code is so tricky that it is better to implement in C than Prolog.

The choice between Prolog and C is not so much about _tricky_. Some things cannot be done in pure Prolog, such as opening a file. So this must be in C. Then there are notably term manipulations that can be done way more efficiently in C, in part because C is faster but also for a large part because we can temporary modify the terms we are working on to avoid the need for tables to keep track of the state. This saves space and turns many operations into O(n), where n is the complexity of the term. Then there is simple deterministic stuff that needs to be fast, such as sort/2 and variations.

> [@EricGT](#):
>
> That is why I say AFAIK it does not use a Virtual Machine such as [WAM](https://en.wikipedia.org/wiki/Warren_Abstract_Machine) or an Intermediate Language such as JVM or CIL.

I don’t think the (SWI-)Prolog VM is conceptually that different from the Java one. There are some clear differences:

- The (SWI-)Prolog VM instruction set is not stable. This means you cannot load VM code on a different version (let alone a different Prolog). There is no real reason why this shouldn’t be possible in theory.
- A Prolog VM has a rather different instruction set. Many instructions are related to unification.
- The WAM is a register VM, but despite some wrong names in the sources, the SWI-Prolog VM is based on a minimal version of the ZIP, which passes arguments over the stacks rather than using registers.
- I don’t know how the JVM deals with stuff such as OS access. The (SWI-)Prolog VM can deal with such things in two ways: add a VM instruction or add a foreign _predicate_. Most not very time critical stuff uses foreign predicates as that keeps the VM small, is easier to manage and even allows loading such extensions at runtime.

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [August 22, 2019, 9:29am UTC](https://swi-prolog.discourse.group/t/curious-how-does-prolog-byte-code-compare-to-net-il-and-some-thoughts-about-enterprise-ready-systems/1101/9 "2019-08-22T09:29:09Z")

</div>

> [@EricGT](#):
>
> So what is the relationship between [vm\_list/1](https://www.swi-prolog.org/pldoc/man?predicate=vm_list/1), the source files [pl-wam.c](https://github.com/SWI-Prolog/swipl-devel/blob/ea88f5f4b6bfe3ad87bbc86a930125fdf2b18842/src/pl-wam.c)  
> [pl-vmi.c](https://github.com/SWI-Prolog/swipl-devel/blob/bf5ff3dae48f263ddceb487899c9ba0b3874c6c0/src/pl-vmi.c) and the implementation of the predicates using [PRED\_IMPL](https://github.com/SWI-Prolog/swipl-devel/search?q=PRED_IMPL&unscoped_q=PRED_IMPL)?
> 
> When I look at the instructions for the WAM, e.g. `unify_value` I would expect to see them in the result from `vm_list(=)` . So what is vm\_list/1 really returning?

A predicate is implemented by what is called the _supervisor_ code. That can be regarded a _preamble_ and depends on how the predicate is defined. If it is foreign, this uses one of the i\_fcall\* instructions which creates the arguments for the C function and calls it. If is a normal predicate it depends on things such as being thread-local, dynamic or static and in the latter case on the indexing opportunities. The supervisor is created on the first call (actually, the initial supervisor is `S_VIRGIN`, which analyses the predicate and replaces itself by the real supervisor on the first call. reloading the predicate resets the supervisor to `S_VIRGIN`).

Unification is a very special case. The VM defines many unification instructions and the predicate is hardly ever called. It is there to support meta calling it (e.g, `maplist(=(x), LIst)`) and such that you can reason about programs using reflexive predicates such as predicate\_property/2. Being foreign, =/2 only has a supervisor and no clauses.

---

<div class="post-metadata">

**Author:** ![grossdan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/grossdan/32/23_2.png) [@grossdan](https://swi-prolog.discourse.group/u/grossdan)\
**Post date:** [August 22, 2019, 4:15pm UTC](https://swi-prolog.discourse.group/t/curious-how-does-prolog-byte-code-compare-to-net-il-and-some-thoughts-about-enterprise-ready-systems/1101/12 "2019-08-22T16:15:38Z")

</div>

Hi,

Thank you for the information.

So, it seems that Prolog would, for an equivalent task be quite slower – speed is mostly gained by those predicates that executed in compiled C.

And my assumption that VMs are inherently slower than native code is not really true … once just in time compiled they run at native speed.

So, i guess, C++ key benefit over, say, Java and .Net, is more control over low level details such as memory layout . I do remember reading a paper that garbage collection done automatically is often more efficient than manual GC in non-garbage collection languages …

Dan

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [August 22, 2019, 7:49pm UTC](https://swi-prolog.discourse.group/t/curious-how-does-prolog-byte-code-compare-to-net-il-and-some-thoughts-about-enterprise-ready-systems/1101/14 "2019-08-22T19:49:54Z")

</div>

> [@grossdan](#):
>
> So, it seems that Prolog would, for an equivalent task be quite slower – speed is mostly gained by those predicates that executed in compiled C.

The granularity of most of the Prolog VM instructions is a lot higher, meaning a single instruction does far more work than it would in an imperative language. The price of a VM (without compiling it) is roughly) threefold:

- Find and jump to the next instruction
- Possible loss of CPU pipelining
- Loose opportunities to schedule instructions smartly due to the split in VM instructions. I.e., if you create a _jumbo_ instruction out of a series of simple VM instructions the compiler may reschedule the instructions in a more efficient way.

There are also some benefits for VM code, especially for Prolog:

- As VM instructions are quite large and very different from the bare metal instructions, the VM code is a lot shorter while using the same bits of the VM interpreter over and over. That reduces cache misses.
- The Prolog garbage collector, debugger and many of the reflexive capabilities reason about the VM instructions. This is lost if we do native code compilation and thus we need either annotations in the code or duplicate representations or give up some of these goodies.

All in all, the debate about the usefulness of compiling Prolog to native code is not settled AFAIK. Surely, some systems showed significant speedup on tight loops running static code, but overall performance on large real wold programs is far less clear.

In the past there was a big deal about adding _jumbo instructions_ to the VM that represents common sequences of primitive instructions. That has the clear value of reducing the size of the compiled program and provide the compilation of the VM to reschedule the instructions in these jumbo instructions. The biggest advantage was attributed to keeping the CPU pipeline running longer. In the old days, a `switch(*PC++)` was typically the end of the CPU pipeline, i.e., the CPU had to start from scratch to load the code and plan the execution. SWI-Prolog, like many modern VM languages uses the GCC extension to get the code addresses for a C label and use `goto ptr`, turning the main VM operation to jump to the next instruction into `goto *PC++`. According to timing I caried out long ago, modern CPUs can deal with that quite efficiently.

The other two still apply and creating jumbo instructions still pays of. Unfortunately it typically implies a lot of code duplication when using e.g., C as language for implementing the VM. This makes the VM harder to maintain and larger. Quite a bit of work has been done in this area. I must admit I followed only some of that from a distance. I never bothered much.

As is, if we want to make SWI-Prolog faster, these are in my perception the most promising:

- Improve the implementation of last call optimization. That is rather clumsy right now.
- Improve clause selection for predicates with some (say 2…10) clauses.
- Reorganize the data representation, notably for 64-bit systems. The tagging scheme for 64-bit is just a slightly modified version of the 32-bit scheme. That can be a lot better, reducing indirections and thus cache misses when accessing data.
- Move some critical foreign predicates to the VM.

---

<div class="post-metadata">

**Author:** ![XVilka](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/xvilka/32/148_2.png) [@XVilka](https://swi-prolog.discourse.group/u/XVilka)\
**Post date:** [August 23, 2019, 5:49am UTC](https://swi-prolog.discourse.group/t/curious-how-does-prolog-byte-code-compare-to-net-il-and-some-thoughts-about-enterprise-ready-systems/1101/16 "2019-08-23T05:49:05Z")

</div>

There is ongoing work on [Scryer Prolog](https://github.com/mthom/scryer-prolog), which aims to be the high performant one, especially since it is written in Rust.

---

<div class="post-metadata">

**Author:** ![grossdan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/grossdan/32/23_2.png) [@grossdan](https://swi-prolog.discourse.group/u/grossdan)\
**Post date:** [August 23, 2019, 6:06am UTC](https://swi-prolog.discourse.group/t/curious-how-does-prolog-byte-code-compare-to-net-il-and-some-thoughts-about-enterprise-ready-systems/1101/17 "2019-08-23T06:06:37Z")

</div>

Interesting,

Too bad that this effort is not focused expanding / improving swi-prolog.

From what I learned about Rust, one key aim is to be fully inoperable with C / C++ – with the intent to port existing code bases to Rust in a piece by piece manner.

Wouldn’t it (have been) great to continue improving on code base that embodies a decade (and more) of experience in Prolog design, by further adding the safety of Rust.

In terms of performance – i think C / C++ is still somewhat faster than Rust, while Rust provides the pointer safety harder to accomplish in C++ (with ownership models and the like).

Dan

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [August 23, 2019, 11:29am UTC](https://swi-prolog.discourse.group/t/curious-how-does-prolog-byte-code-compare-to-net-il-and-some-thoughts-about-enterprise-ready-systems/1101/18 "2019-08-23T11:29:53Z")

</div>

I’m not very convinced using Rust for developing a VM. Better management of object lifetime is of course great, especially for applications. For a VM though you typically need dedicated techniques. Just consider clauses. Prolog must keep them after deletion until no thread has an open call on the involved predicate with an older _generation_ and until it is no longer involved in an explicit database reference as returned (for example) using `assertz/2`. You cannot do this using reference counting as multiple threads running the same clauses will cause a huge slowdown. These things are in SWI-Prolog handled using a dedicated garbage collector. Generic GC is also problematic as it scans far too much for finding references, seriously slowing down Prolog programs with many gigabytes of in use memory.

I’ve tried using the [Boehm garbage collector](https://en.wikipedia.org/wiki/Boehm_garbage_collector) as getting rid of old objects safely is a big challenge when using lock free algorithms. There are still various traces in the code. Initially it seemed quite nice, but I reverted quickly after running some really big programs and observing a very large performance degradation.

Keri and I also tried reference counting on several objects, but we needed to abandon that idea for most object types as well.

So yes, I believe you can relatively quickly implement a safe multi-threaded Prolog in Rust that will perform well single threaded. I doubt it will do a good job on real concurrent workloads though. It may be possible to bypass Rust’s default coping mechanisms to improve on that. Possibly you still gain in terms of readability. Possibly you loose.

---

<div class="post-metadata">

**Author:** ![EricGT](https://avatars.discourse-cdn.com/v4/letter/e/f1d935/32.png) [@EricGT](https://swi-prolog.discourse.group/u/EricGT)\
**Post date:** [August 24, 2019, 1:01pm UTC](https://swi-prolog.discourse.group/t/curious-how-does-prolog-byte-code-compare-to-net-il-and-some-thoughts-about-enterprise-ready-systems/1101/19 "2019-08-24T13:01:14Z")

</div>

2 posts were split to a new topic: [Is SWI-Prolog being used in domains that requires multi-threading at scale?](https://swi-prolog.discourse.group/t/is-swi-prolog-being-used-in-domains-that-requires-multi-threading-at-scale/1110)

---

<div class="post-metadata">

**Author:** ![EricGT](https://avatars.discourse-cdn.com/v4/letter/e/f1d935/32.png) [@EricGT](https://swi-prolog.discourse.group/u/EricGT)\
**Post date:** [August 24, 2019, 10:55am UTC](https://swi-prolog.discourse.group/t/curious-how-does-prolog-byte-code-compare-to-net-il-and-some-thoughts-about-enterprise-ready-systems/1101/21 "2019-08-24T10:55:43Z")

</div>

10 posts were split to a new topic: [Encouraging industry about Prolog](https://swi-prolog.discourse.group/t/encouraging-industry-about-prolog/1106)

---

<div class="post-metadata">

**Author:** ![hnbeck](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/hnbeck/32/3149_2.png) [@hnbeck](https://swi-prolog.discourse.group/u/hnbeck)\
**Post date:** [March 9, 2021, 12:07pm UTC](https://swi-prolog.discourse.group/t/curious-how-does-prolog-byte-code-compare-to-net-il-and-some-thoughts-about-enterprise-ready-systems/1101/23 "2021-03-09T12:07:57Z")

</div>

Hi,  
to be honest I don’t understand every detail in the posts here. But my conclusion would be: if doing some adaption such that the SWI VM runs on .NET CLI, SWI Prolog would run in the .Net ecosystem. But how much effort would that be? Nearly impossible or some work but doable? The motivation here would be participate the .NET ecosystem via CLI.

But I have to read more about the implementation of SWI, its interesting topic.

Cheers

Hans

---

<div class="post-metadata">

**Author:** ![grossdan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/grossdan/32/23_2.png) [@grossdan](https://swi-prolog.discourse.group/u/grossdan)\
**Post date:** [March 9, 2021, 12:48pm UTC](https://swi-prolog.discourse.group/t/curious-how-does-prolog-byte-code-compare-to-net-il-and-some-thoughts-about-enterprise-ready-systems/1101/24 "2021-03-09T12:48:12Z")

</div>

I read somewhere that the Java VM is not build for optimizing tail recursion – so a programming language, such as Clojure (a Lisp on the Java VM), that could significantly benefit from such an optimization does not have it.

Don’t know what the situation for CLi is …

Dan

---

<div class="post-metadata">

**Author:** ![CapelliC](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/capellic/32/17_2.png) [@CapelliC](https://swi-prolog.discourse.group/u/CapelliC)\
**Post date:** [March 9, 2021, 6:20pm UTC](https://swi-prolog.discourse.group/t/curious-how-does-prolog-byte-code-compare-to-net-il-and-some-thoughts-about-enterprise-ready-systems/1101/25 "2021-03-09T18:20:31Z")

</div>

Now that M$ is (literally) buying into FOSS, I have reconsidered C# and took some time to help on SO about using [SwiPLCSharp](https://github.com/SWI-Prolog/contrib-swiplcs).

Have you already tried it ?

As Jan remarked some time ago, SWI-Prolog is a complex system, that needs a strict control over essential resources, and conflicts with other complex runtimes can be a nightmare…

---

<div class="post-metadata">

**Author:** ![hnbeck](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/hnbeck/32/3149_2.png) [@hnbeck](https://swi-prolog.discourse.group/u/hnbeck)\
**Post date:** [March 10, 2021, 6:00pm UTC](https://swi-prolog.discourse.group/t/curious-how-does-prolog-byte-code-compare-to-net-il-and-some-thoughts-about-enterprise-ready-systems/1101/26 "2021-03-10T18:00:34Z")

</div>

Thanks for the pointer. This lib was unknown to me. But the point is, it is an connector, meaning that SWI Prolog would run unmanaged as normal, right?
