# Another day, another predicate, another choicepoint!

**URL:** <https://swi-prolog.discourse.group/t/another-day-another-predicate-another-choicepoint/6816>\
**Category:** General\
**Created:** [September 3, 2023, 7:15pm UTC](https://swi-prolog.discourse.group/t/another-day-another-predicate-another-choicepoint/6816 "2023-09-03T19:15:44Z")\
**Posts on this page:** 1\
**Showing post:** 11

<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:** [September 4, 2023, 7:30am UTC](https://swi-prolog.discourse.group/t/another-day-another-predicate-another-choicepoint/6816/11 "2023-09-04T07:30:42Z")

</div>

Can squeeze out more performance, at the cost of readability:

```prolog
nth1_elem(I, L, E) :-
    ( integer(I)
    -> I @>= 1
    ; var(I)
    ),
    nth1_elem_(L, 1, I, E).

nth1_elem_([H|T], U, I, E) :-
    ( ( U == I
        -> ! 
        ; U = I
        ),
        % After cut
        H = E,
        ( T == []
            % No more elements to check
        -> !
        ; true
        )
    ; U1 is U + 1,
        nth1_elem_(T, U1, I, E)
    ).

```

Performance:

```prolog
?- garbage_collect, numlist(1, 20_000_000, NL),
time((nth1_elem(I, NL, E), false)).
% 60,000,001 inferences, 1.300 CPU in 1.301 seconds (100% CPU, 46167444 Lips)

?- garbage_collect, time((between(1, 10_000, Len),
numlist(1, Len, NL), nth1_elem(I, NL, 1_000), false)).
% 100,118,001 inferences, 5.001 CPU in 5.006 seconds (100% CPU, 20020685 Lips)

?- garbage_collect, time((between(1, 10_000, Len),
length(L, Len), nth1_elem(I, L, E), false)).
% 150,055,001 inferences, 3.349 CPU in 3.351 seconds (100% CPU, 44811446 Lips)

```

---

_[View the full topic](https://swi-prolog.discourse.group/t/another-day-another-predicate-another-choicepoint/6816)._
