It is often said that compared to SQL, Prolog lacks
goal reordering. But is it true that query planning boils
down to goal reordering? I found an example
which is more than goal reordering. You don't get anc2/2
from anc/2 by simple goal reordering, even if both were
formulated with edge/2. Take this example here (*):
setup :- between(1,1024,N), M is N//2, assertz(edge(M,N)), fail.
setup :- edge(M,N), assertz(edge2(N,M)), fail.
setup.
anc(X,Y) :- edge(X, Y).
anc(X,Y) :- edge(X, Z), anc(Z, Y).
anc2(X,Y) :- edge2(Y, X).
anc2(X,Y) :- edge2(Y, Z), anc2(X, Z).
Its the same transitive closure, only once computed from
the left and the other time computed from the right:
?- time((between(1,1000,_), anc(0,1024), fail; true)).
% 3,076,001 inferences, 0.178 CPU in 0.181 seconds (98% CPU, 17298884 Lips) true.
?- time((between(1,1000,_), anc2(0,1024), fail; true)).
% 37,001 inferences, 0.003 CPU in 0.003 seconds (99% CPU, 14659667 Lips) true.
(*) I am using edge/2 and edge2/2 so that the testing also works
for a Prolog system that has only first argument indexing.
Woa! The JavaScript JIT compiler is quite impressive. I now
ported Dogelog runtime to Python as well, so that I can compare
JavaScript and Python, and tested without clause indexing:
between(L,H,L) :- L =< H.
between(L,H,X) :- L < H, Y is L+1, between(Y,H,X).
setup :- between(1,255,N), M is N//2, assertz(edge(M,N)), fail.
setup :- edge(M,N), assertz(edge2(N,M)), fail.
setup.
anc(X,Y) :- edge(X, Y).
anc(X,Y) :- edge(X, Z), anc(Z, Y).
anc2(X,Y) :- edge2(Y, X).
anc2(X,Y) :- edge2(Y, Z), anc2(X, Z).
:- setup.
:- time((between(1,10,_), anc2(0,255), fail; true)).
:- time((between(1,10,_), anc(0,255), fail; true)).
The results are:
/* Python 3.10.0rc1 */
% Wall 188 ms, trim 0 ms
% Wall 5537 ms, trim 0 ms
/* JavaScript Chrome 92.0.4515.159 */
% Wall 5 ms, trim 0 ms
% Wall 147 ms, trim 0 ms
Mostowski Collapse schrieb am Mittwoch, 18. August 2021 um 02:23:06 UTC+2:
It is often said that compared to SQL, Prolog lacks
goal reordering. But is it true that query planning boils
down to goal reordering? I found an example
which is more than goal reordering. You don't get anc2/2
from anc/2 by simple goal reordering, even if both were
formulated with edge/2. Take this example here (*):
setup :- between(1,1024,N), M is N//2, assertz(edge(M,N)), fail.
setup :- edge(M,N), assertz(edge2(N,M)), fail.
setup.
anc(X,Y) :- edge(X, Y).
anc(X,Y) :- edge(X, Z), anc(Z, Y).
anc2(X,Y) :- edge2(Y, X).
anc2(X,Y) :- edge2(Y, Z), anc2(X, Z).
Its the same transitive closure, only once computed from
the left and the other time computed from the right:
?- time((between(1,1000,_), anc(0,1024), fail; true)).
% 3,076,001 inferences, 0.178 CPU in 0.181 seconds (98% CPU, 17298884 Lips) true.
?- time((between(1,1000,_), anc2(0,1024), fail; true)).
% 37,001 inferences, 0.003 CPU in 0.003 seconds (99% CPU, 14659667 Lips) true.
(*) I am using edge/2 and edge2/2 so that the testing also works
for a Prolog system that has only first argument indexing.
Thats a factor 37.8 faster! I tested the a variant of
the Albufeira instructions Prolog VM aka ZIP, which
was also the inspiration for SWI-Prolog.
Open Source:
The Python Version of the Dogelog Runtime https://github.com/jburse/dogelog-moon/tree/main/devel/runtimepy
The Python Test Harness https://gist.github.com/jburse/bf6c01c7524f2611d606cb88983da9d6#file-test-py Mostowski Collapse schrieb am Donnerstag, 19. August 2021 um 20:00:43 UTC+2:
Woa! The JavaScript JIT compiler is quite impressive. I now
ported Dogelog runtime to Python as well, so that I can compare
JavaScript and Python, and tested without clause indexing:
between(L,H,L) :- L =< H.
between(L,H,X) :- L < H, Y is L+1, between(Y,H,X).
setup :- between(1,255,N), M is N//2, assertz(edge(M,N)), fail.
setup :- edge(M,N), assertz(edge2(N,M)), fail.
setup.
anc(X,Y) :- edge(X, Y).
anc(X,Y) :- edge(X, Z), anc(Z, Y).
anc2(X,Y) :- edge2(Y, X).
anc2(X,Y) :- edge2(Y, Z), anc2(X, Z).
:- setup.
:- time((between(1,10,_), anc2(0,255), fail; true)).
:- time((between(1,10,_), anc(0,255), fail; true)).
The results are:
/* Python 3.10.0rc1 */
% Wall 188 ms, trim 0 ms
% Wall 5537 ms, trim 0 ms
/* JavaScript Chrome 92.0.4515.159 */
% Wall 5 ms, trim 0 ms
% Wall 147 ms, trim 0 ms
Mostowski Collapse schrieb am Mittwoch, 18. August 2021 um 02:23:06 UTC+2:
It is often said that compared to SQL, Prolog lacks
goal reordering. But is it true that query planning boils
down to goal reordering? I found an example
which is more than goal reordering. You don't get anc2/2
from anc/2 by simple goal reordering, even if both were
formulated with edge/2. Take this example here (*):
setup :- between(1,1024,N), M is N//2, assertz(edge(M,N)), fail.
setup :- edge(M,N), assertz(edge2(N,M)), fail.
setup.
anc(X,Y) :- edge(X, Y).
anc(X,Y) :- edge(X, Z), anc(Z, Y).
anc2(X,Y) :- edge2(Y, X).
anc2(X,Y) :- edge2(Y, Z), anc2(X, Z).
Its the same transitive closure, only once computed from
the left and the other time computed from the right:
?- time((between(1,1000,_), anc(0,1024), fail; true)).
% 3,076,001 inferences, 0.178 CPU in 0.181 seconds (98% CPU, 17298884 Lips)
true.
?- time((between(1,1000,_), anc2(0,1024), fail; true)).
% 37,001 inferences, 0.003 CPU in 0.003 seconds (99% CPU, 14659667 Lips) true.
(*) I am using edge/2 and edge2/2 so that the testing also works
for a Prolog system that has only first argument indexing.
So this week , was coding Python as if there
were no tomorrow, only to arrive at the conclusion:
- Ha Ha Python is useless
Lets see. Next I will try to bring first argument clause
indexing also to the Python version and redo the
Datalog-ish benchmark.
Mostowski Collapse schrieb am Donnerstag, 19. August 2021 um 20:01:48 UTC+2:
Thats a factor 37.8 faster! I tested the a variant of
the Albufeira instructions Prolog VM aka ZIP, which
was also the inspiration for SWI-Prolog.
Open Source:
The Python Version of the Dogelog Runtime https://github.com/jburse/dogelog-moon/tree/main/devel/runtimepy
The Python Test Harness https://gist.github.com/jburse/bf6c01c7524f2611d606cb88983da9d6#file-test-py
Mostowski Collapse schrieb am Donnerstag, 19. August 2021 um 20:00:43 UTC+2:
Woa! The JavaScript JIT compiler is quite impressive. I now
ported Dogelog runtime to Python as well, so that I can compare JavaScript and Python, and tested without clause indexing:
between(L,H,L) :- L =< H.
between(L,H,X) :- L < H, Y is L+1, between(Y,H,X).
setup :- between(1,255,N), M is N//2, assertz(edge(M,N)), fail.
setup :- edge(M,N), assertz(edge2(N,M)), fail.
setup.
anc(X,Y) :- edge(X, Y).
anc(X,Y) :- edge(X, Z), anc(Z, Y).
anc2(X,Y) :- edge2(Y, X).
anc2(X,Y) :- edge2(Y, Z), anc2(X, Z).
:- setup.
:- time((between(1,10,_), anc2(0,255), fail; true)).
:- time((between(1,10,_), anc(0,255), fail; true)).
The results are:
/* Python 3.10.0rc1 */
% Wall 188 ms, trim 0 ms
% Wall 5537 ms, trim 0 ms
/* JavaScript Chrome 92.0.4515.159 */
% Wall 5 ms, trim 0 ms
% Wall 147 ms, trim 0 ms
Mostowski Collapse schrieb am Mittwoch, 18. August 2021 um 02:23:06 UTC+2:
It is often said that compared to SQL, Prolog lacks
goal reordering. But is it true that query planning boils
down to goal reordering? I found an example
which is more than goal reordering. You don't get anc2/2
from anc/2 by simple goal reordering, even if both were
formulated with edge/2. Take this example here (*):
setup :- between(1,1024,N), M is N//2, assertz(edge(M,N)), fail.
setup :- edge(M,N), assertz(edge2(N,M)), fail.
setup.
anc(X,Y) :- edge(X, Y).
anc(X,Y) :- edge(X, Z), anc(Z, Y).
anc2(X,Y) :- edge2(Y, X).
anc2(X,Y) :- edge2(Y, Z), anc2(X, Z).
Its the same transitive closure, only once computed from
the left and the other time computed from the right:
?- time((between(1,1000,_), anc(0,1024), fail; true)).
% 3,076,001 inferences, 0.178 CPU in 0.181 seconds (98% CPU, 17298884 Lips)
true.
?- time((between(1,1000,_), anc2(0,1024), fail; true)).
% 37,001 inferences, 0.003 CPU in 0.003 seconds (99% CPU, 14659667 Lips)
true.
(*) I am using edge/2 and edge2/2 so that the testing also works
for a Prolog system that has only first argument indexing.
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 296 |
Nodes: | 16 (2 / 14) |
Uptime: | 53:35:18 |
Calls: | 6,650 |
Calls today: | 2 |
Files: | 12,200 |
Messages: | 5,330,494 |