Mercury csharp grade "optimized code" |
Yap Prolog 6.2.0 |
Yield Prolog C# 2008 "optimized code" |
Yield Prolog C# Mono 2.0 "optimized code" |
XSB 3.1 |
SWI-Prolog 5.10.2 |
Yield Prolog Javascript Firefox 4 "optimized code" |
JLog 1.3.4 |
Yield Prolog Python 2.7 "optimized code" |
Yield Prolog IronPython 2.0RC2 "optimized code" |
|
queens "optimized code" (seconds) |
0.25 |
0.68 | 0.91 |
1.04 |
2.34 |
4.95 | 20.3 |
23.1 | 42.7 |
91.4 |
queens "naive code" (seconds) |
0.27 | 7.06 | 8.93 | 194 | 297 | 1462 |
% Find all solutions of an 11 by 11 board.For the Yield Prolog benchmarks, the "naive code" literally translates the Prolog, and the function arguments are always assumed to be general. The "optimized code" allows the function arguments to be typed. For example, we require the first two arguments to rangeList to be integers so that we don't have to call YP.getValue(). Also, the attack function is only used by queens3 to check if there is an attack, and attack never binds any variables, so the "optimized code" converts it to a normal function hasAttack which returns a boolean.
% The \+ with the fail is a trick to make it find all solutions.
queensBenchmark :- time(\+ (queens(11, _Qs), fail)).
queens(N,Qs) :- rangeList(1,N,Ns), queens3(Ns,[],Qs).
queens3(UnplacedQs, SafeQs, Qs) :-
selectq(Q, UnplacedQs, UnplacedQs1),
\+ attack(Q,SafeQs),
queens3(UnplacedQs1,[Q|SafeQs],Qs).
queens3([],Qs,Qs).
attack(X,Xs) :- attack3(X, 1, Xs).
attack3(X,N,[Y|_]) :- X =:= Y+N ; X =:= Y-N.
attack3(X,N,[_|Ys]) :- N1 is N+1, attack3(X,N1,Ys).
rangeList(M,N,[M]) :- M >= N, !.
rangeList(M,N,[M|Tail]) :- M1 is M+1, rangeList(M1,N,Tail).
selectq(X,[X|Xs],Xs).
selectq(X,[Y|Ys],[Y|Zs]) :- selectq(X,Ys,Zs).