Thread overview | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
|
June 26, 2015 Why aren't Ranges Interfaces? | ||||
---|---|---|---|---|
| ||||
I have been learning D over the past three weeks and I came to the chapter in "Programming in D" on Ranges. And I am a little confused on the choice to make Ranges based on the methods you have in the struct, but not use a interface. With all of the isInputRange!R you have to write everywhere, it just seems like it would have made a lot more sense and made everyone's jobs easier if the different types of Ranges where just interfaces that you could inherit from. The only reason I can think of to not do it this way is the weird distinction between structs and classes in D. |
June 26, 2015 Re: Why aren't Ranges Interfaces? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jack Stouffer | On Friday, 26 June 2015 at 18:37:51 UTC, Jack Stouffer wrote: > The only reason I can think of to not do it this way is the weird distinction between structs and classes in D. If anything, C++ is the weird one in having two keywords that mean the same thing... But the reason comes down to three things: 1) They are! http://dlang.org/phobos/std_range_interfaces.html That works in some cases, but not all. They aren't typically used though because of the other reasons: 2) interfaces have an associated runtime cost, which ranges wanted to avoid. They come with hidden function pointers and if you actually use it through them, you can get a performance hit. In theory, the compiler could optimize that in some cases, making the interface syntax sugar for the isInputRange thing, but that still doesn't solve... 3) Ranges don't just meet an interface, they can also have other optional elements, like infiniteness or additional methods, that aren't expressible through inherited methods. Some of that could be solved by having many interfaces together, but not all of it. Infiniteness, for example, is seen by the fact that empty is a constant false rather than a method. Perhaps you could reengineer this too, but then the interfaces don't look as clean as they otherwise would. (Look at how many variants there are in that std.range.interfaces, and it still doesn't actually cover everything!) These two items together mean ranges typically don't fit the interface model well. If you're looking at a case where it is a good fit though, you can use the provided interfaces and wrappers. |
June 26, 2015 Re: Why aren't Ranges Interfaces? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jack Stouffer | On Friday, 26 June 2015 at 18:37:51 UTC, Jack Stouffer wrote:
> I have been learning D over the past three weeks and I came to the chapter in "Programming in D" on Ranges. And I am a little confused on the choice to make Ranges based on the methods you have in the struct, but not use a interface. With all of the isInputRange!R you have to write everywhere, it just seems like it would have made a lot more sense and made everyone's jobs easier if the different types of Ranges where just interfaces that you could inherit from.
>
> The only reason I can think of to not do it this way is the weird distinction between structs and classes in D.
They're essentially compile-time interfaces.
I would prefer having a real name/binding implementation for this, like contract.
|
June 26, 2015 Re: Why aren't Ranges Interfaces? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adam D. Ruppe | Thanks for the reply! I understand the reasoning now.
On Friday, 26 June 2015 at 18:46:03 UTC, Adam D. Ruppe wrote:
> 2) interfaces have an associated runtime cost, which ranges wanted to avoid. They come with hidden function pointers and if you actually use it through them, you can get a performance hit.
How much of a performance hit are we talking about? Is the difference between using an interface and not using one noticeable?
|
June 26, 2015 Re: Why aren't Ranges Interfaces? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jack Stouffer | On Friday, 26 June 2015 at 19:26:57 UTC, Jack Stouffer wrote: > Thanks for the reply! I understand the reasoning now. > > On Friday, 26 June 2015 at 18:46:03 UTC, Adam D. Ruppe wrote: >> 2) interfaces have an associated runtime cost, which ranges wanted to avoid. They come with hidden function pointers and if you actually use it through them, you can get a performance hit. > > How much of a performance hit are we talking about? Is the difference between using an interface and not using one noticeable? It can be in a tight loop. http://eli.thegreenplace.net/2013/12/05/the-cost-of-dynamic-virtual-calls-vs-static-crtp-dispatch-in-c this is for C++, but it applies directly to D. Interestingly, CRTP is a gigantic C++ hack that D gets for free with alias this. |
June 26, 2015 Re: Why aren't Ranges Interfaces? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jack Stouffer | On Friday, 26 June 2015 at 19:26:57 UTC, Jack Stouffer wrote:
> How much of a performance hit are we talking about? Is the difference between using an interface and not using one noticeable?
It can be huge difference if you take inlning in mind. LDC is capable of flattening most simple range-based pipelines into simple in-place loop during optimization - something you can't do with interfaces unless some sort of runtime profiling optimization is involved.
|
June 26, 2015 Re: Why aren't Ranges Interfaces? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jack Stouffer | On Fri, 26 Jun 2015 19:26:56 +0000, Jack Stouffer wrote:
> Thanks for the reply! I understand the reasoning now.
>
> On Friday, 26 June 2015 at 18:46:03 UTC, Adam D. Ruppe wrote:
>> 2) interfaces have an associated runtime cost, which ranges wanted to avoid. They come with hidden function pointers and if you actually use it through them, you can get a performance hit.
>
> How much of a performance hit are we talking about? Is the difference between using an interface and not using one noticeable?
For some real numbers, a while back I wrote up several variations on a "big data" type process for a presentation on memory performance and the importance of cache hits. The classic Java-style class-based version ran in 4 seconds while the lazy range struct version ran in 0.83 seconds. Using LDC to inline (impossible with interfaces) brought the runtime down to 0.38 seconds.
|
June 26, 2015 Re: Why aren't Ranges Interfaces? | ||||
---|---|---|---|---|
| ||||
Posted in reply to rsw0x | On Friday, 26 June 2015 at 19:40:41 UTC, rsw0x wrote:
> On Friday, 26 June 2015 at 19:26:57 UTC, Jack Stouffer wrote:
>> Thanks for the reply! I understand the reasoning now.
>>
>> On Friday, 26 June 2015 at 18:46:03 UTC, Adam D. Ruppe wrote:
>>> 2) interfaces have an associated runtime cost, which ranges wanted to avoid. They come with hidden function pointers and if you actually use it through them, you can get a performance hit.
>>
>> How much of a performance hit are we talking about? Is the difference between using an interface and not using one noticeable?
>
> It can be in a tight loop.
>
> http://eli.thegreenplace.net/2013/12/05/the-cost-of-dynamic-virtual-calls-vs-static-crtp-dispatch-in-c
>
> this is for C++, but it applies directly to D. Interestingly, CRTP is a gigantic C++ hack that D gets for free with alias this.
In my code I need to use polymorphism. But, if I replace the code for my interface inheritance with an inherit of an class that implements empty methods and my methods just override the empty ones I get an essentially free performance boost 0_0? Good to know; thanks for the link.
|
June 26, 2015 Re: Why aren't Ranges Interfaces? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jack Stouffer | On 06/26/2015 11:37 AM, Jack Stouffer wrote: > easier if the different types of Ranges where > just interfaces that you could inherit from. If you think you need polymorphic interfaces, the next chapter talks about inputRangeObject(): http://ddili.org/ders/d.en/ranges_more.html#ix_ranges_more.polymorphism,%20run-time Ali |
Copyright © 1999-2021 by the D Language Foundation