-
Notifications
You must be signed in to change notification settings - Fork 154
ADDED: ...@ //2, a faster ... //0 at the end only #3093
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
An explicit |
Source: mthom#3080 (comment) Currently, I get: ?- phrase_from_file(...@, "pio.pl"). freeze:freeze(_A,user:render_step(true,'$dropped_value',position_and_lines_read(0,0),_A)). How to best solve this?
af8812a
to
9692fee
Compare
I think I solved it! Please have a look! |
So more than a factor 100 faster for regular lists. And seems fine with |
I think one of the most impressive features is that this lets us automatically stop reading from a file as soon as we find what we are looking for, is this true? In this way, the potential improvement for very large files is in fact unbounded. |
Right, I was not sure what file to take.
While the frozen goal is removed for a leaf answer, on backtracking it is reestablished such that also the last character of the file can be read. |
@jjtolton, have you tried it? |
@jjtolton, did you look at it? |
Somehow I was missing these notifications. :- use_module(library(pio)).
:- use_module(library(dcgs)).
:- use_module(library(lists)).
:- use_module(library(time)).
demo :-
E = 24, N is 2^E, length(L, N),
time(phrase(...@, L)), nl,
time(phrase(..., L)), nl, nl.
?- once(demo).
%@ % CPU time: 0.044s, 38 inferences
%@
%@ % CPU time: 6.129s, 83_886_139 inferences
%@
%@
%@ true. Wow -- 140x speedup, 8 or 9 factors less inferences?? |
Any reason why this couldn't just be integrated into I guess we would need this anyway to actually close the file. Maybe there's a way to invert the control here and make the file closing not depend on the non-terminal that is being called, in a way that just the stock |
The file is automatically closed on deterministic success, failure or exception, via The design question is: Should |
Integrating it into |
Considering the current implementation of % This could be the definition of `... //0`.
elipsis(S0, S) :-
% The test is only done once for each call of `... //0`
% and immediately dispatches to the old implementation.
% This means that the overhead doesn't appear on backtracking
% of this non-terminal.
( S == [] ->
'$skip_max_list'(_,_,S0,S1),
elipsis_(S1, S)
; elipsis_(S0, S)
).
% Basically the current definition of `... //0` but optimized.
% (Also pure and simpler!??)
elipsis_(S, S).
elipsis_([_|S0], S) :- elipsis_(S0, S).
% The current definition of `... //0` for reference.
...(Cs0,Cs) :- % Isn't this "a tiny overhead everywhere"?
Cs0 == [],
!,
Cs0 = Cs.
... --> [] | [_], ... . Some benchmarks of the worst case scenario: ?- Ls = [_,_], time((phrase(({between(1,1000000,_)}, ..., "a"), Ls), false; true)).
% CPU time: 2.099s, 23_000_149 inferences
Ls = [_A,_B].
?- Ls = [_,_], time((phrase(({between(1,1000000,_)}, elipsis_, "a"), Ls), false; true)).
% CPU time: 1.346s, 15_000_149 inferences
Ls = [_A,_B].
?- Ls = [_,_], time((phrase(({between(1,1000000,_)}, elipsis, "a"), Ls), false; true)).
% CPU time: 1.513s, 17_000_149 inferences
Ls = [_A,_B]. Notice that it's actually faster than the current implementation even with the check. Here's the best case scenario: ?- length(Ls, 1000000), time((phrase(({between(1,100,_)}, ...), Ls), false; true)).
% CPU time: 35.875s, 500_001_141 inferences
Ls = [_A,_B,_C,_D,_E,_F,_G,_H,_I,_J,_K,_L,_M,_N,_O,_P,_Q,_R,_S,_T|...].
?- length(Ls, 1000000), time((phrase(({between(1,100,_)}, elipsis_), Ls), false; true)).
% CPU time: 8.508s, 200_000_941 inferences
Ls = [_A,_B,_C,_D,_E,_F,_G,_H,_I,_J,_K,_L,_M,_N,_O,_P,_Q,_R,_S,_T|...].
?- length(Ls, 1000000), time((phrase(({between(1,100,_)}, elipsis), Ls), false; true)).
% CPU time: 0.331s, 1_141 inferences
Ls = [_A,_B,_C,_D,_E,_F,_G,_H,_I,_J,_K,_L,_M,_N,_O,_P,_Q,_R,_S,_T|...]. Absurd gains! I believe using A bigger brained solution to this might be to do this in the expansion of Anyway, this is just general optimization stuff which isn't that important for this PR. I think the vanilla |
The difference between |
Source:
Currently, I get:
How to best solve this?