Jump to page: 1 2
Thread overview
dmd 0.141: acessing associative array and -release compiler switch - array.d
Dec 29, 2005
Ivan Cibiri
Dec 31, 2005
Chris Lajoie
Re: dmd 0.141: accessing associative array and -release compiler switch
Dec 31, 2005
Ivan Cibiri
Dec 31, 2005
Ameer Armaly
Re: dmd 0.141: acessing associative array and -release compiler switch
Jan 01, 2006
Dave
Jan 01, 2006
Kris
Jan 03, 2006
Dave
Jan 03, 2006
Oskar Linde
Jan 03, 2006
Dave
Jan 03, 2006
Kris
December 29, 2005
Hello,

when acessing associative array, there is different exception thrown, depends if -release compiler switch is used or not. See attached source file. Compile it with out -release switch and run. Then compile it with -release switch and run.

Problem is that when compiled using -release switch, it generates Access Violation exception instead of ArrayBoundsError exception. I expect the same exception to be generated in both cases, otherways it is necessary to have different application logic to recover from the exception.

In my opinion, behaviour is correct when std.arry.ArrayBoundsError exception is thrown, in both cases.

Ivan.



December 30, 2005
"Ivan Cibiri" <Ivan_member@pathlink.com> wrote in message news:dp17ln$iic$1@digitaldaemon.com...
> Hello,
>
> when acessing associative array, there is different exception thrown,
> depends if
> -release compiler switch is used or not. See attached source file. Compile
> it
> with out -release switch and run. Then compile it with -release switch and
> run.
>
> Problem is that when compiled using -release switch, it generates Access
> Violation exception instead of ArrayBoundsError exception. I expect the
> same
> exception to be generated in both cases, otherways it is necessary to have
> different application logic to recover from the exception.
>
> In my opinion, behaviour is correct when std.arry.ArrayBoundsError
> exception is
> thrown, in both cases.
>
> Ivan.

Array bounds checking is turned off in release versions for performance, unlike certain other slow, paranoid languages ;)  Hence, you get an access violation in the release build.


December 31, 2005
Jarrett Billingsley wrote:
> Array bounds checking is turned off in release versions for performance, unlike certain other slow, paranoid languages ;)  Hence, you get an access violation in the release build. 

I don't like the idea that my debug and release builds might run differently. Should that behavior be acceptable? Maybe bounds checking should always be on unless there's a pragma(NoBoundsCheck) (or something).. or a compiler switch.

Chris
December 31, 2005
In article <dp5me6$v86$1@digitaldaemon.com>, Chris Lajoie says...
>
>Jarrett Billingsley wrote:
>> Array bounds checking is turned off in release versions for performance, unlike certain other slow, paranoid languages ;)  Hence, you get an access violation in the release build.
>
>I don't like the idea that my debug and release builds might run differently. Should that behavior be acceptable? Maybe bounds checking should always be on unless there's a pragma(NoBoundsCheck) (or something).. or a compiler switch.
>
>Chris
I agree with Chris, because I expect the same behaviour from debug and release
builds. I understand that switching off bounds chcecking improves performance,
however it changes behaviour of application in some cases. Of course, turning on
release build you should understand what it does to your application. Maybe more
control on level of optimizations would be useful (e.g. bounds checking off),
but on the other side, it would be more complicated to play (and possible waste
of time) with many different switches.
Current solution for debug and release build is simple to use, but for me it is
little bit annoying that in debug build you can fine tune recovery from
different exceptions, but in release build it does not work because diffent
exceptions are thrown as a result turned off bounds checking.
Simillar situation is with asserts in debug and release builds. Both, bounds
chcecking and asserts helps you debug your code, but as a result of using this
features you have to expect possible different behaviour of application when
compiled with or without release switch. It means that you have to run your test
suite against debug build and then also against release build.

Ivan.


December 31, 2005
"Ivan Cibiri" <Ivan_member@pathlink.com> wrote in message news:dp5rrm$12uo$1@digitaldaemon.com...
> In article <dp5me6$v86$1@digitaldaemon.com>, Chris Lajoie says...
>>
>>Jarrett Billingsley wrote:
>>> Array bounds checking is turned off in release versions for performance,
>>> unlike certain other slow, paranoid languages ;)  Hence, you get an
>>> access
>>> violation in the release build.
>>
>>I don't like the idea that my debug and release builds might run differently. Should that behavior be acceptable? Maybe bounds checking should always be on unless there's a pragma(NoBoundsCheck) (or something).. or a compiler switch.
>>
>>Chris
> I agree with Chris, because I expect the same behaviour from debug and
> release
> builds. I understand that switching off bounds chcecking improves
> performance,
> however it changes behaviour of application in some cases. Of course,
> turning on
> release build you should understand what it does to your application.
> Maybe more
> control on level of optimizations would be useful (e.g. bounds checking
> off),
> but on the other side, it would be more complicated to play (and possible
> waste
> of time) with many different switches.
> Current solution for debug and release build is simple to use, but for me
> it is
> little bit annoying that in debug build you can fine tune recovery from
> different exceptions, but in release build it does not work because
> diffent
> exceptions are thrown as a result turned off bounds checking.
> Simillar situation is with asserts in debug and release builds. Both,
> bounds
> chcecking and asserts helps you debug your code, but as a result of using
> this
> features you have to expect possible different behaviour of application
> when
> compiled with or without release switch. It means that you have to run
> your test
> suite against debug build and then also against release build.
>
> Ivan.
>
>
Yes, since debug builds are just that.  They are designed to actively look for bugs and to inform you of what happened; release builds are designed for when you're 99 percent sure that everything's going to go just right, and don't necessarily have to do that kind of checking.  When in doubt, you can always just leave off both switches.


January 01, 2006
In article <dp5me6$v86$1@digitaldaemon.com>, Chris Lajoie says...
>
>Jarrett Billingsley wrote:
>> Array bounds checking is turned off in release versions for performance, unlike certain other slow, paranoid languages ;)  Hence, you get an access violation in the release build.
>
>I don't like the idea that my debug and release builds might run differently. Should that behavior be acceptable? Maybe bounds checking should always be on unless there's a pragma(NoBoundsCheck) (or something).. or a compiler switch.
>
>Chris

But -release *is* the compiler switch <g>

Ok, I know that the OP example was just that (an example) and therefore contrived, but D provides better ways to write that loop and most like it to avoid even the possibility of an ArrayBoundsError:

int* result = key in array;
if(result)
writefln("Key %s found and associated value is %s", key, *result);

or

if(key in array)
writefln("Key %s found and associated value is %s", key, array[key]);

Since perhaps you could leave out the EH, either of these would use less code and probably faster anyhow.

Same is true of other types of arrays by using the built-in foreach instead of direct indexing.

Point is, there are expedient ways built right into the language to often work around even the need for bounds checking, bounds checking can add a lot of runtime overhead, and it can't always be reliably optimized away by the compiler, so part of what -release does is remove it. The alternative would logically conclude with a different switch for every type of runtime check or contract statement.


January 01, 2006
"Dave" <Dave_member@pathlink.com> wrote...
>
> Point is, there are expedient ways built right into the language to often
> work
> around even the need for bounds checking, bounds checking can add a lot of
> runtime overhead, and it can't always be reliably optimized away by the
> compiler, so part of what -release does is remove it. The alternative
> would
> logically conclude with a different switch for every type of runtime check
> or
> contract statement.

That's very true. But I think the problem here is actually the API? I can't find the thread right now, but there was one a few months back where we were asking Walter to revert back part of his prior change to the AA API, to take care of this issue and a couple of others. From what I recall, a concensus was reached in terms of how it should really operate <*gasp*> but I think by that time Walter had already had enough, after changing the API once :)

I'll try to locate the thread ~ since it would be good to eliminate this kind of concern (in the only place it apparently happens).


January 03, 2006
In article <dp7bmj$212n$1@digitaldaemon.com>, Kris says...
>
>
>"Dave" <Dave_member@pathlink.com> wrote...
>>
>> Point is, there are expedient ways built right into the language to often
>> work
>> around even the need for bounds checking, bounds checking can add a lot of
>> runtime overhead, and it can't always be reliably optimized away by the
>> compiler, so part of what -release does is remove it. The alternative
>> would
>> logically conclude with a different switch for every type of runtime check
>> or
>> contract statement.
>
>That's very true. But I think the problem here is actually the API? I can't find the thread right now, but there was one a few months back where we were asking Walter to revert back part of his prior change to the AA API, to take care of this issue and a couple of others. From what I recall, a concensus was reached in terms of how it should really operate <*gasp*> but I think by that time Walter had already had enough, after changing the API once :)
>
>I'll try to locate the thread ~ since it would be good to eliminate this kind of concern (in the only place it apparently happens).
>

Is this part of it: http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D.dtl/136 ?

Just a quick glance at some of the posts suggests that the current API would be Ok if double lookups (or pointer sytax to avoid them) could be avoided.

If so, what if the AA implementation (as opposed to the API or the compiler) was changed so that code like the following would avoid a full-fledged double lookup?

// if(key in array) {
//    writefln("Key %s found and associated value is %s", key, array[key]);
// }

*Maybe* this could be done in the current implementation w/o a huge amount of work. The trick would be to make sure it was thread-safe and not add a bunch of overhead elsewhere, I think.

Basically, if the last lookup is the same as the current lookup (for the same AA), then why go through the entire lookup again?

Just a thought...

- Dave


January 03, 2006
Dave wrote:

> Is this part of it:
> http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D.dtl/136
> ?
> 
> Just a quick glance at some of the posts suggests that the current API would be
> Ok if double lookups (or pointer sytax to avoid them) could be avoided.
> 
> If so, what if the AA implementation (as opposed to the API or the compiler) was
> changed so that code like the following would avoid a full-fledged double
> lookup?
> 
> // if(key in array) {
> //    writefln("Key %s found and associated value is %s", key, array[key]);
> // }
> 
> *Maybe* this could be done in the current implementation w/o a huge amount of
> work. The trick would be to make sure it was thread-safe and not add a bunch of
> overhead elsewhere, I think.

> Basically, if the last lookup is the same as the current lookup (for the same
> AA), then why go through the entire lookup again?

You could just keep a cache of the last lookup for each AA. No need to make it thread-safe as the AA isn't anyway. Such a single node cache would probably not affect the performance very much for the general usage case and might even improve it in some cases.

The current AA implementation already has a magic 1st bucket. Why not make the next N buckets contain caches.

(But using the pointer returned from key in array to optimise time critical code doesn't seem very ugly to me...)

/Oskar
January 03, 2006
In article <dpdfhq$2jvj$1@digitaldaemon.com>, Oskar Linde says...
>
>Dave wrote:
>
>> Is this part of it: http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D.dtl/136 ?
>> 
>> Just a quick glance at some of the posts suggests that the current API would be Ok if double lookups (or pointer sytax to avoid them) could be avoided.
>> 
>> If so, what if the AA implementation (as opposed to the API or the compiler) was changed so that code like the following would avoid a full-fledged double lookup?
>> 
>> // if(key in array) {
>> //    writefln("Key %s found and associated value is %s", key, array[key]);
>> // }
>> 
>> *Maybe* this could be done in the current implementation w/o a huge amount of work. The trick would be to make sure it was thread-safe and not add a bunch of overhead elsewhere, I think.
>
>> Basically, if the last lookup is the same as the current lookup (for the same AA), then why go through the entire lookup again?
>
>You could just keep a cache of the last lookup for each AA. No need to make it thread-safe as the AA isn't anyway. Such a single node cache would probably not affect the performance very much for the general usage case and might even improve it in some cases.
>
>The current AA implementation already has a magic 1st bucket. Why not make the next N buckets contain caches.
>
>(But using the pointer returned from key in array to optimise time critical code doesn't seem very ugly to me...)
>
>/Oskar

Exactly what I had in mind, except I'm not so sure the threading issue can be dismissed so easily, because this is a cache seperate from the userspace data.

Whereas the AA implementation key/value pairs can always be thread synchronized in userland, the cache can't, and shouldn't be seen as a userland responsibility because the user doesn't have direct control over it.

You could always do something like turn the caching off if more than one thread is active, and you are no worse off than now w.r.t. double lookups.

Or I suppose you could ensure that if the cached key is updated in the hashtable, then the cached value is updated as well. Hmmm, that should take care of the problem I guess.

- Dave


« First   ‹ Prev
1 2