# Compare/3 faster than arithmetic why?

**URL:** https://swi-prolog.discourse.group/t/compare-3-faster-than-arithmetic-why/5682
**Category:** Help!
**Created:** [August 15, 2022, 10:01am UTC](https://swi-prolog.discourse.group/t/compare-3-faster-than-arithmetic-why/5682 "2022-08-15T10:01:10Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![brebs](https://avatars.discourse-cdn.com/v4/letter/b/e9c0ed/32.png) [@brebs](https://swi-prolog.discourse.group/u/brebs)
#### Post date: [August 15, 2022, 10:01am UTC](https://swi-prolog.discourse.group/t/compare-3-faster-than-arithmetic-why/5682/1 "2022-08-15T10:01:10Z")

</div>

In SWI-Prolog 8.4.3:

```prolog
?- time((between(0, 50_000_000, N), N > 49_000_000)).
% 98,000,005 inferences, 2.912 CPU in 2.914 seconds (100% CPU, 33653791 Lips)
N = 49000001 .

?- time((between(0, 50_000_000, N), compare(>, N, 49_000_000))).
% 98,000,003 inferences, 2.411 CPU in 2.413 seconds (100% CPU, 40645761 Lips)
N = 49000001 .

```

Why is compare/3 significantly faster? Seems unintuitive 😀

---

<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 15, 2022, 10:10am UTC](https://swi-prolog.discourse.group/t/compare-3-faster-than-arithmetic-why/5682/2 "2022-08-15T10:10:20Z")

</div>

Have you followed the code al the way down even into the C level code?

I use to use format/2,3 only when needed for outputing values as I thought it was time expensive. Then Jan W. noted in an unrelated reply that it was actually quite fast when used correctly and often used for more then just formatting, think conversion. After looking for examples in my list of trusted repositories I started to see many uses of format/2,3 beyond what I expected.

So don’t take the name of a predicate or description of its use to be limited to just that. Also don’t bring the baggage of ideas from imperative and functional languages along with you when reasoning about Prolog code, go look at the source.

If you want a predicate that is way beyond what it seems to be learn arg/3. 🙂

As I like to say, get the code working correctly before making it faster.

* * *

Did you notice the difference in lips? 33653791 vs 40645761.  
I don’t know if or how much that will skew the results but I would understand that more for such questions.

---

<div class="post-metadata">

### Author: ![kuniaki.mukai](https://avatars.discourse-cdn.com/v4/letter/k/c67d28/32.png) [@kuniaki.mukai](https://swi-prolog.discourse.group/u/kuniaki.mukai)
#### Post date: [August 15, 2022, 11:26am UTC](https://swi-prolog.discourse.group/t/compare-3-faster-than-arithmetic-why/5682/3 "2022-08-15T11:26:56Z")

</div>

Sorry, but I could not catch the point, in particular why `format/2` is related here. But I tested the comparison for curiosity, in which I haven’t seen a significant difference.

```prolog
?- time((between(0, 50_000_000, N), N > 49_000_000)).
% 98,000,005 inferences, 3.410 CPU in 3.423 seconds (100% CPU, 28739637 Lips)
N = 49000001 .

?- time((between(0, 50_000_000, N), compare(>, N, 49_000_000))).
% 98,000,003 inferences, 3.351 CPU in 3.362 seconds (100% CPU, 29243816 Lips)
N = 49000001 .

```

---

<div class="post-metadata">

### Author: ![brebs](https://avatars.discourse-cdn.com/v4/letter/b/e9c0ed/32.png) [@brebs](https://swi-prolog.discourse.group/u/brebs)
#### Post date: [August 15, 2022, 12:23pm UTC](https://swi-prolog.discourse.group/t/compare-3-faster-than-arithmetic-why/5682/4 "2022-08-15T12:23:25Z")

</div>

My original comparison (2.4 vs 2.9 seconds), with compare/3 faster, was run on an AMD Ryzen 7 5800H CPU, using x86\_64.

On an Intel Core m3-6Y30 running SWI-Prolog 8.5.13 on x86\_64, the difference is 6.6 vs 8.3 seconds.

On an Apple M1 Pro running 8.4.3 [supplied via brew](https://github.com/Homebrew/homebrew-core/blob/86a872d9d0db6caa340392e621f52ed6632905a5/Formula/swi-prolog.rb) (presumably native arm64), the diffence is insignificant at 2.4 vs 2.5 seconds.

Perhaps this shows that there is scope for perforrmance improvement on x86\_64 by changing method of numerical comparison.

---

<div class="post-metadata">

### Author: ![abaljeu](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/abaljeu/32/136_2.png) [@abaljeu](https://swi-prolog.discourse.group/u/abaljeu)
#### Post date: [August 15, 2022, 2:40pm UTC](https://swi-prolog.discourse.group/t/compare-3-faster-than-arithmetic-why/5682/5 "2022-08-15T14:40:42Z")

</div>

compare/3 examines the terms and sees which is less. It works on all kinds of terms, not just numbers. It doesn’t perform arithmetic, just examines the internal representation. [SWI-Prolog -- Manual](https://www.swi-prolog.org/pldoc/man?section=standardorder)

\>/2 evaluates each terms using built-in arithmetic. It works on all terms that represent arithmetic expression.

I think you should prefer compare or @\>

---

<div class="post-metadata">

### Author: ![brebs](https://avatars.discourse-cdn.com/v4/letter/b/e9c0ed/32.png) [@brebs](https://swi-prolog.discourse.group/u/brebs)
#### Post date: [August 15, 2022, 3:16pm UTC](https://swi-prolog.discourse.group/t/compare-3-faster-than-arithmetic-why/5682/6 "2022-08-15T15:16:47Z")

</div>

```prolog
?- time((between(0, 50_000_000, N), N @> 49_000_000)).
% 98,000,003 inferences, 2.282 CPU in 2.283 seconds (100% CPU, 42951988 Lips)
N = 49000001 .

```

That’s a nice performance improvement, by adding the ampersand, when both variables are known to be of type integer 😀

E.g. this would be unintended:

```prolog
?- 5 @> 5.0.
true.

```

---

<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 16, 2022, 3:54pm UTC](https://swi-prolog.discourse.group/t/compare-3-faster-than-arithmetic-why/5682/7 "2022-08-16T15:54:36Z")

</div>

For another timing on the list, load a file using `swipl -O` that holds

```prolog
p(N) :-
    between(0, 50_000_000, N),
    N > 49_000_000.

```

and do `?- time(p(N)).` That gives me the best time as it used optimized arithmetic done by the VM itself. All the others call a “foreign” predicate. compare/3 is indeed standard order comparison and thus should be compared to @\>/2, which -for me- is a little faster than compare/3.
