On Thu, 29 Sep 2011 20:14:01 -0400, Peter Alexander <peter.alexander...@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

Reply via email to