]> Repositorios git - scryer-prolog.git/commitdiff
ENHANCED: use a fast test for the expected case of chars in atom_chars/2 etc.
authorMarkus Triska <[email protected]>
Thu, 24 Apr 2025 16:19:05 +0000 (18:19 +0200)
committerMark Thom <[email protected]>
Tue, 8 Jul 2025 05:38:12 +0000 (22:38 -0700)
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.

src/lib/builtins.pl

index ca07e0c68598ac5cd1eaf3f33fc14ef433b05d38..df7696f9f7bb31bf420100411a3f1959a5b6f6b5 100644 (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) ->
        !
     ;  Cs == [] ->
        !
     ).
-chars_or_vars([C|Cs], PI) :-
+chars_or_vars_([C|Cs], PI) :-
     (  nonvar(C) ->
        (  atom(C),
           atom_length(C, 1) ->
           chars_or_vars(Cs, PI)
        ;  throw(error(type_error(character, C), PI))
        )
-    ;  chars_or_vars(Cs, PI)
+    ;  chars_or_vars_(Cs, PI)
     ).