Style guide / optimisation...

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Style guide / optimisation...

emacstheviking
Hi,

I just knocked these out to read a file into memory for DCG practice over files. I know they might not be the best they can which is why I am asking for how to make it more efficient...

file_codes(From, Out) :-
open(From, read, S),
file_read_buf(S, [], get_code, -1, Out),
close(S).

file_chars(From, Out) :-
open(From, read, S),
file_read_buf(S, [], get_char, end_of_file, Out),
close(S).

file_read_buf(S, Acc, Fetcher, Eof, Out) :-
Reader =.. [Fetcher, S, Chr],
call(Reader),
( Chr == Eof -> reverse(Acc, Out) ; file_read_buf(S, [Chr|Acc], Fetcher, Eof, Out)).

I wanted to avoid using =.. every time I read another bit of the file; it just feels like it should be outside the loop, I tried this but it didn't do what I expected:

    file_read_buf(S, [], get_code(S, _Chr), -1, Out)

So, how can I make this more efficient and prolog-gy?

Thanks,
Sean.


_______________________________________________
Users-prolog mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/users-prolog
Reply | Threaded
Open this post in threaded view
|

Re: Style guide / optimisation...

Daniel Diaz-3
Hi

You are right =.. is not very efficient. You can use call/2-N to avoid this
http://www.gprolog.org/manual/html_node/gprolog042.html#sec194

Also the reverse is time and space consuming. This is strange because you use an accumulator: this is generally used to avoid append or reverse. In fact the accumulator is not needed and avoids the use of reverse.

Here is the resulting version:

file_codes(From, Out) :-
    open(From, read, S),
    file_read_buf(S, get_code, -1, Out),
    close(S).

file_chars(From, Out) :-
    open(From, read, S),
    file_read_buf(S, get_char, end_of_file, Out),
    close(S).

file_read_buf(S, Fetcher, Eof, Out) :-
    call(Fetcher, S, Chr),
    (   Chr \== Eof ->
        Out = [Chr|Out1],
        file_read_buf(S, Fetcher, Eof, Out1)
    ;
        Out = []
    ).



Daniel

Le 14/10/2014 00:42, emacstheviking a écrit :
file_codes(From, Out) :-
open(From, read, S),
file_read_buf(S, [], get_code, -1, Out),
close(S).

file_chars(From, Out) :-
open(From, read, S),
file_read_buf(S, [], get_char, end_of_file, Out),
close(S).

file_read_buf(S, Acc, Fetcher, Eof, Out) :-
Reader =.. [Fetcher, S, Chr],
call(Reader),
( Chr == Eof -> reverse(Acc, Out) ; file_read_buf(S, [Chr|Acc], Fetcher, Eof, Out)).

I wanted to avoid using =.. every time I read another bit of the file; it just feels like it should be outside the loop, I tried this but it didn't do what I expected:

    file_read_buf(S, [], get_code(S, _Chr), -1, Out)

So, how can I make this more efficient and prolog-gy?



--
Ce message a été vérifié par MailScanner pour des virus ou des polluriels et rien de suspect n'a été trouvé.
_______________________________________________
Users-prolog mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/users-prolog