[mercury-users] First solution in csharp without try/catch
Jeff Thompson
jeff at thefirst.org
Sun Jan 15 04:03:08 AEDT 2012
On 1/13/2012 8:46 PM, Mark Brown wrote:
> Hi Jeff,
>
> On 12-Jan-2012, Jeff Thompson<jeff at thefirst.org> wrote:
>> On 1/9/2012 11:15 PM, Jeff Thompson wrote:
>>> On 1/8/2012 8:58 PM, Mark Brown wrote:
>>>> Hi Jeff,
>>>>
>>>> On 06-Jan-2012, Jeff Thompson<jeff at thefirst.org> wrote:
>>>>> Hello again. I'm using the csharp grade to compile the following.
>>>>>
>>>>> :- pred multiPred(int::out) is multi.
>>>>> multiPred(1).
>>>>> multiPred(2).
>>>>>
>>>>> :- pred test is semidet.
>>>>> test :- if multiPred(X), X> 0 then true else fail.
>>>>>
>>>>> In pred test, in the if statement, when "multiPred(X), X> 0" first
>>>>> succeeds, the predicate succeeds, else fails. The compiled C# code
>>>>> works
>>>>> correctly. But the implementation throws a new runtime.Commit()
>>>>> exception
>>>>> when it first succeeds, and catches this in an outer try/catch block
>>>>> (see
>>>>> below). I can understand why the authors would have implemented it this
>>>>> way, but using exceptions for message passing in normal operation is
>>>>> very
>>>>> inefficient.
>>>>> Is there another way (where the implementation doesn't use try/catch) to
>>>>> make a semidet predicate which succeeds on the first solution of some
>>>>> code
>>>>> block?
>>>> I don't think there is a more efficient solution,
>>>>
>>>> short of avoiding
>>>> nondet
>>>> code to begin with (i.e., implement your own search in det/semidet code).
>> I'm still struggling with this one. I set pred test to the "fast version"
>> which tests "X> 2" which fails and does not throw an exception. A
>> benchmark with 10,000,000 calls to this takes only 0.45 seconds. (Awesome!)
>>
>> When I set the test back to "X> 0" where it throws the exception, the
>> benchmark takes 171 seconds. That's 380 times as long. This is what
>> "message passing with exceptions is inefficient" means. It really hurts.
>> Is there no help to be gotten from the compiler?
> Well, the first case never "succeeds on the first solution", so it doesn't
> actually measure the functionality you're asking for.
Thanks for the feedback. I did the first case where it doesn't throw
the exception as a base line to test how quickly the generated code can
search through all the cases (very quickly). The idea is that if I only
need it to search through one case, it could be even quicker if it used
an efficient mechanism to commit.
> How does the version
> using exceptions compare to the handwritten version using yield?
As above, the times for Mercury code are 0.45 seconds for the baseline
and 171 seconds if it commits. For the "yield" code it is 2.33 seconds
for the baseline and 2.03 if it commits after one solution. As
expected, since the "yield" code uses the same infrastructure in both
cases, it takes less time to search less solutions. But the baseline
Mercury code is faster than the "yield" code which allocates an iterator
object on the heap for every "foreach" loop (as opposed to Mercury's
more efficient approach of using continuations).
X > 2 X > 0
Mercury 11.07 0.45 171
"yield" 2.33 2.03
>
> Also, how do the savings, if any, compare to the amount of time required to
> perform a typical search? The reason I ask is that the project I work on
> uses nondet search extensively, but the searches are millisecond-scale at
> the very least. Hence microsecond-scale costs of exceptions are not as
> painful for us as the rule-of-thumb would suggest.
>
Can you give a concrete example or a reference for a nondet search so I
know we are talking about the same thing? (All I can think is that you
are talking about converting all my code to run in a meta interpreter.)
Thanks,
- Jeff
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mercurylang.org/archives/users/attachments/20120114/4b99c711/attachment.html>
More information about the users
mailing list