Possible way to achieve lazy loading with const objects

Steven Schveighoffer schveiguy at yahoo.com
Fri Sep 30 05:52:55 PDT 2011


On Thu, 29 Sep 2011 20:14:01 -0400, Peter Alexander  
<peter.alexander.au at gmail.com> wrote:

> On 29/09/11 8:01 PM, Steven Schveighoffer wrote:
>> Again, I ask, what is a real-world example of something that needs lazy
>> caching (or where lazy caching significantly helps performance) for
>> comparison. You have already stated that you appreciate it's not const,
>> so you must have *something* that needs it.
>
> 1. A renderer lazily caching world transform matrices.

How does this relate to opEquals?

> 2. Collision detection queries often cache recent intermediate results  
> due to spacial coherency between queries.

Surely you are not doing collision detection with opEquals?

>
> 3. A simple asset loader may lazily load assets on demand (rather than  
> having to eagerly load things up front).

This is a good one.  The thought of loading a resource just to throw it  
away because const won't let you store it is not really acceptable.

I can see this being related to opEquals more than the others.  I wonder  
how often this would affect opEquals in practice.

I have to think about this, and how it could possibly be solvable.  I  
suspect we may need to do something that supports logical const  
specifically for this problem (i.e. not generalized logical const).  BTW,  
see my other thread "logical const without casts" for a possible solution.

> 4. String hashes are cached all over the place for fast resource look  
> ups.

strings have no place to store a cache.  Plus resource lookup is not  
opEquals.

>
> I'm honestly quite amazed that I have to justify my belief that caching  
> is useful, and commonly used. Caches are everywhere: your CPU has  
> multiple levels of caches, you hard disk has caches, your browser  
> caches, domain lookups are cached; and they're all lazy, too. Lazy  
> caching is a cornerstone of optimisation.

Oh, I am not questioning the value or usefulness of caching in general.   
What I'm wondering is how often it's needed for comparisons.

What we are discussing is why opEquals should not be const, not why all  
functions should not be const.

>> So far, I don't think it's a very common requirement. It certainly
>> doesn't seem like it's so important that the entire body of D code in
>> existence should have to deal with mutable opEquals. The fact that it's
>> mutable now is really a legacy D1 issue.
>
> Inline assembler isn't a common requirement either, but that's no  
> argument to ignore it.

Inline assembler is a basic requirement, even if it's not used often.   
Many low-level pieces depend on it.

Besides, having inline assembler does *not* affect code that does not use  
inline assembler.  This is not the same thing as making opEquals cater to  
non-const implementations.

> I suppose something like __restrict isn't very important to you either.  
> It's certainly used a lot less than lazy caching. However, it's worth  
> pointing out that __restrict was introduced into compilers through  
> popular demand by people that needed it. These things are real and  
> should not be ignored.

I'm unaware of __restrict, so I can't really comment on it.

But I'll respond to the general argument that something that isn't used  
often is still useful:

Yes, things can be included that are used infrequently, as long as the  
inclusion of such support does not adversely affect code that doesn't need  
it.  The problem we have here is:

1. opEquals is not const, so you cannot compare const objects.  This is  
downright unacceptable.
2. A compromise solution where opEquals is both const and non const in  
Object sacrifices performance and simplicity for the benefit of having the  
*possibility* of obj == obj working for lazy-caching opEquals.
3. Is it worth making the majority of opEquals implementations (i.e. those  
that are const-only) lower performing in order to allow for the  
possibility?  How much do we gain by downgrading const opEquals?
4. Is it worth making existing code stop compiling in order to switch to  
const opEquals exclusively?

My opinion is:

1. we need const opEquals.  There is no debate on this I think.
2. The compromise solution is not worth the gain.  I'd rather have most of  
my objects compare as quickly as possible.
3. It should be possible to create a mutable opEquals and have it hook  
with obj == obj.  This is different than the compromise solution, which  
puts both const and non-const opEquals in Object.  This means we need to  
reengineer how the compiler does opEquals for objects.
4. Yes, it is worth breaking existing compilation to switch to const  
opEquals in Object.

-Steve


More information about the Digitalmars-d mailing list