I think the comparison made by @CapelliC [that has been deleted] is misleading. The OP asks for a predicate to compare two lists and check if they are the same, except for the last two elements that may appear swapped (which is different from a predicate that just swaps the last two elements of a single list). Thus, a fairer comparison should call the predicates to be compared with two instantiated lists as input.
My suggestion is to modify perf_belt/3 as follows:
/* File: last2swap_perf.pl
Author: Carlo
Created: Dec 12 2021
Purpose: compare answers to https://stackoverflow.com/q/70281408/874024
*/
:- module(last2swap_perf, [cmp/2]).
:- meta_predicate perf_belt(+,+,3).
% CapelliC's solutions
% append/2 based
last2swap_app2(A,B,[U,V]):-
append([C,[U,V]],A),
append([C,[V,U]],B).
% append/3 based
last2swap_app3(A,B,[U,V]):-
append(C,[U,V],A),
append(C,[V,U],B).
% slago' solution
lastTwoReversed(L1, L2, [X1,X2]) :-
reverse(L1, [X1,X2|Rest]),
reverse(L2, [X2,X1|Rest]).
% brebs' answer
swap_last_2([Elem1, Elem2|Tail], SwappedLst, Last2) :-
swap_last_2_(Tail, Elem1, Elem2, [], RevSwappedLst, Last2),
reverse(RevSwappedLst, SwappedLst).
% This swaps the last 2 elements
swap_last_2_([], Elem1, Elem2, SoFar, [Elem1, Elem2|SoFar], [Elem2, Elem1]).
swap_last_2_([Head|Tail], Elem1, Elem2, SoFar, SwappedLst, Last2) :-
% Move the elements along
swap_last_2_(Tail, Elem2, Head, [Elem1|SoFar], SwappedLst, Last2).
%! %%% minimal perf utility
perf_belt(NRep, LList, Pred) :- % <== NEW VERSION PROPOSED
make_lists(LList, List1, List2),
time( forall(between(1, NRep, _), % <== TWO INSTANTIATED LISTS AS INPUT
call(Pred, List1, List2, _)) ).
make_lists(N, List1, List2) :-
N1 is N - 1,
N2 is N - 2,
numlist(1, N2, Prefix),
append(Prefix, [N1, N], List1),
append(Prefix, [N, N1], List2).
cmp(NRep,LList) :-
perf_belt(NRep,LList,last2swap_app2),
perf_belt(NRep,LList,last2swap_app3),
perf_belt(NRep,LList,lastTwoReversed),
perf_belt(NRep,LList,swap_last_2).
Fairer results Running on SWI-Prolog, version 8.4.1, we can see that double reverse is not so bad.
?- cmp(100, 100).
% 71,101 inferences, 0.000 CPU in 0.000 seconds (?% CPU, Infinite Lips)
% 20,101 inferences, 0.000 CPU in 0.000 seconds (?% CPU, Infinite Lips)
% 20,701 inferences, 0.000 CPU in 0.000 seconds (?% CPU, Infinite Lips)
% 20,401 inferences, 0.000 CPU in 0.000 seconds (?% CPU, Infinite Lips)
true.
?- cmp(100, 1000).
% 701,101 inferences, 0.047 CPU in 0.047 seconds (100% CPU, 14956821 Lips)
% 200,101 inferences, 0.031 CPU in 0.031 seconds (100% CPU, 6403232 Lips)
% 200,701 inferences, 0.016 CPU in 0.016 seconds (100% CPU, 12844864 Lips)
% 200,401 inferences, 0.016 CPU in 0.016 seconds (100% CPU, 12825664 Lips)
true.
?- cmp(1000, 1000).
% 7,011,001 inferences, 0.438 CPU in 0.437 seconds (100% CPU, 16025145 Lips)
% 2,001,001 inferences, 0.219 CPU in 0.219 seconds (100% CPU, 9147433 Lips)
% 2,007,001 inferences, 0.141 CPU in 0.141 seconds (100% CPU, 14272007 Lips)
% 2,004,001 inferences, 0.141 CPU in 0.141 seconds (100% CPU, 14250674 Lips)
true.