Re: Ann: SWI-Prolog 7.1.0

Paulo Moura <[email protected]>
Newsgroups gmane.comp.ai.prolog.swi
Message-ID <[email protected]>
Hi Jan,

On 07/12/2013, at 09:54, Jan Wielemaker <[email protected]> wrote:

> On 12/06/2013 11:28 PM, Paulo Moura wrote:
>> Hi,
>> 
>> Sorry about the very late reply to this post (on defaulty data
>> structures) but I have some experience here that I want to share.
>> 
>> On 28/11/2013, at 07:10, Richard A. O'Keefe <[email protected]>
>> wrote:
>> 
>>> 
>>> On 28/11/2013, at 7:00 AM, Jan Wielemaker wrote:
>>> 
>>>> Alan,
>>>> 
>>>> Good to point this out!  Yes, if everyone follows the Craft of
>>>> Prolog's rules on this, [] \== '[]' is not needed.  But ..
>>>> 
>>>> - It uses a lot more memory (1 cell for joe and 3 for
>>>> word(joe)).
>>> 
>>> This is seriously misleading.
>>> 
>>> The design rules given in the Craft of Prolog do NOT generate
>>> wrappers except to do one of two things: - to package together two
>>> or more piece of information - to distinguish one case from
>>> another.
>>> 
>>> One of the reasons that I wrote that section of the book was that I
>>> was disturbed by the amount of Prolog code I had seen that 
>>> *over*-used wrappers, so I wanted simple clear guidelines that 
>>> would *only* result in wrappers that paid for themselves.
>>> 
>>> By the way, I used to have a 4MB desktop machine in 1990. It had 1
>>> core and rand about 30 MHz. I now have an 8GB desktop machine,
>>> which has 4 cores, each of them 100 times faster.
>>> 
>>> Using 2 extra words of memory is a GOOD thing IF it pays for itself
>>> by making the program simpler and clearer.
>>> 
>>> As a case in point, when David Warren wrote the Quintus compiler, 
>>> he used defaulty data structures everywhere.
>>> 
>>> I rewrote it to never use defaulty data structures. And it ran 20%
>>> faster. It even took less memory, because the trick was to
>>> carefully design *every* case in the data type. ...
>> 
>> During my sabbatical, when visiting K.U.Leuven, I had the chance to
>> help two researchers there that were using complex Prolog
>> applications to deal with stuff like big data. They were using a fast
>> Prolog system (YAP) but still their applications run for long hours.
>> I offered my help and, thanks to Richard's book on defaulty data
>> representation, I quickly recognized a familiar pattern: cuts
>> everywhere and the Prolog runtime repeatedly  creating choice-points
>> just to cut them some point later while it tried clause after clause
>> after clause. I asked a few questions (I had no familiarity with the
>> code) and rewrote that part of the code. It took me around one hour
>> in each case to avoid the defaulty data representation. The resulting
>> applications speedup was impressive. Around 40% for one of the cases,
>> a bit less for the other.
>> 
>> It's not always easy to avoid using defaulty data structures. But the
>> benefits in both code clarity and performance can be quite
>> significant :-) Specially when the defaulty bits are where the
>> application spends most of its time.
> 
> All true.  Just, Prolog systems can also nicely generate a switch-on-tag
> from code such as
> 
> do(X) :- atom(X), ....
> do(X) :- number(X), ...
> do(X) :- string(X), ...
> 
> etc.  Properly implemented, the above should be faster than code like this
> 
> do(atom(X)) :-
> do(number(X)) :-
> do(string(X)) :-

But there's an important difference here that is not apparent if a switch-on-tag would solve. Often, you have something like:

do(X) :- atom(X), !, ....
do(X) :- number(X), !, ...
do(X) :- string(X), !, ...

Does the approach you mention avoids creating a choice-point for do(X) calls that is then discarded by the cuts? The advantage (I observed) of the alternative solution:

do(atom(X)) :-
do(number(X)) :-
do(string(X)) :-

is that no choice-point is created for calls to do(X) where X is instantiated. Plus, from my readings about Prolog implementations, those that do a switch-on-tag approach do so only when the tests are the standard *built-in* term type predicates, which doesn't help with the also common cases where the tests are calls to user-defined predicates.

> Alas, SWI-Prolog only looks at the clause head.  Possibly YAP does the
> same.  Ideally, Prolog examines the code for unification and type checks
> (and whatever it can understand) that follow the head to support its
> indexing.
> 
> That said, I agree that defaulty data structures can positively influence
> readability and declarative behaviour.

And, in cases such as the ones described, also avoid the performance penalty of repeatedly creating and destroying choice-points, plus looking for the correct clause by trying them one by one instead of jumping straight to it (thanks to indexing of clause heads).

Cheers,

Paulo

-----------------------------------------------------------------
Paulo Moura
Logtalk developer

Email: <mailto:[email protected]>
Web:   <http://logtalk.org/>
-----------------------------------------------------------------
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.