ENHANCED: use a fast test for the expected case of chars in atom_chars/2 etc.

Suggested by Oleg Finkelstein, thank you a lot!

Example, before this change:

    ?- t+\(length(As, 1_000_000), maplist(=(a), As), time(atom_chars(A, As))).
       % CPU time: 0.693s, 7_000_041 inferences
       true.

Now:

    ?- t+\(length(As, 1_000_000), maplist(=(a), As), time(atom_chars(A, As))).
       % CPU time: 0.080s, 40 inferences
       true.

This also partially ameliorates #2907.
This commit is contained in:
Markus Triska
2025-04-24 18:19:05 +02:00
committed by Mark Thom
parent b12d1ece17
commit e9bb41f0d6

View File

@@ -1719,20 +1719,27 @@ must_be_number(N, PI) :-
). ).
chars_or_vars(Cs, _) :- chars_or_vars(Cs, PI) :-
( '$is_partial_string'(Cs) ->
% use a fast test for the expected case
true
; chars_or_vars_(Cs, PI)
).
chars_or_vars_(Cs, _) :-
( var(Cs) -> ( var(Cs) ->
! !
; Cs == [] -> ; Cs == [] ->
! !
). ).
chars_or_vars([C|Cs], PI) :- chars_or_vars_([C|Cs], PI) :-
( nonvar(C) -> ( nonvar(C) ->
( atom(C), ( atom(C),
atom_length(C, 1) -> atom_length(C, 1) ->
chars_or_vars(Cs, PI) chars_or_vars(Cs, PI)
; throw(error(type_error(character, C), PI)) ; throw(error(type_error(character, C), PI))
) )
; chars_or_vars(Cs, PI) ; chars_or_vars_(Cs, PI)
). ).