May 16, 2016
On Monday, 16 May 2016 at 22:28:04 UTC, ag0aep6g wrote:
>
> I can't say that I understand the setup you describe. But are you sure that iota has a higher cost than (ab)using a slice?
>
> I mean, they're pretty much exactly the same: an offset, a length, and an increment operation. If inlining doesn't fail, they should perform the same, no?

Maybe. I should test this...
>
> And if iota does perform worse for some reason, I feel like there must be a way to implement something that matches the speed of the slice without inheriting its ugliness.

:)
The point is, that in my model the slice has a meaning itself. So, the language provides one of a needed constructs...

May 16, 2016
On Monday, 16 May 2016 at 22:30:38 UTC, ag0aep6g wrote:
> On 05/16/2016 11:33 PM, Alex wrote:
>> Well... not wanting to have a variable, which stores numbers, which are
>> natural numbers, beginning with zero, used for counting only.
>
> But you have such a variable: b. I may still be missing the point.

Yeah, the b variable is contained in the E objects and is unavoidable, as the E object has to save the region he is at and some number has to be reported by the E object to the describing objects in case of an action.
The point is, that the slice of numbers, contained in the E object is done from nothing. Well, from a void pointer. So, I get ordinal numbers from void and not from a list.
Just as the reality (in my head) is: you can count something without having written the natural numbers before you start to count... Especially, I don't have to create some strange structs containing just a number, as I expect to have some millions of them.
May 17, 2016
On 05/17/2016 12:43 AM, Alex wrote:
> The point is, that in my model the slice has a meaning itself. So, the
> language provides one of a needed constructs...

Huh? As far as I understand, the pointer of the slice is invalid, and you never dereference it. What kind of additional meaning can the slice carry then? It's practically just a struct of two `size_t`s.
May 17, 2016
On 05/17/2016 12:53 AM, Alex wrote:
> Just as the reality (in my head) is: you can count something without
> having written the natural numbers before you start to count...

iota does that, too. A iota struct doesn't store all the numbers it will emit. Just like a slice, a iota struct stores two numbers: the first and the amount of numbers. Iterating over it means counting, not reading pre-generated numbers from a list.

> Especially, I don't have to create some strange structs containing just
> a number, as I expect to have some millions of them.

Some million slices will take just as much space as some million iota structs. Storing a slice isn't free. If you create the slices on the fly, you can do that with iota too. No need to store them beforehand.
May 17, 2016
On Monday, 16 May 2016 at 22:54:31 UTC, ag0aep6g wrote:
> On 05/17/2016 12:43 AM, Alex wrote:
>> The point is, that in my model the slice has a meaning itself. So, the
>> language provides one of a needed constructs...
>
> Huh? As far as I understand, the pointer of the slice is invalid, and you never dereference it. What kind of additional meaning can the slice carry then? It's practically just a struct of two `size_t`s.

the elements of the slice are accessible just for reading, right, but with them I reference the data in other objects.

May 17, 2016
On Monday, 16 May 2016 at 23:01:44 UTC, ag0aep6g wrote:
> On 05/17/2016 12:53 AM, Alex wrote:
>> Just as the reality (in my head) is: you can count something without
>> having written the natural numbers before you start to count...
>
> iota does that, too. A iota struct doesn't store all the numbers it will emit. Just like a slice, a iota struct stores two numbers: the first and the amount of numbers. Iterating over it means counting, not reading pre-generated numbers from a list.
>
>> Especially, I don't have to create some strange structs containing just
>> a number, as I expect to have some millions of them.
>
> Some million slices will take just as much space as some million iota structs. Storing a slice isn't free. If you create the slices on the fly, you can do that with iota too. No need to store them beforehand.

the space is the same, yes...
Added this to my test:

import std.conv : to;
import std.datetime;
size_t aM = 5; size_t bM = 80;
void f1() {auto io = iota(aM,bM);}
void f2() {auto sl = testFunc(arr, aM ,bM);}
auto r = benchmark!(f1, f2)(100_000);
auto f0Result = to!Duration(r[0]); // time f1 took to run 10,000 times
auto f1Result = to!Duration(r[1]); // time f2 took to run 10,000 times
writeln("f1: ", f0Result);
writeln("f2: ", f1Result);

with dmd test44.d -release
the results are:
f1: 692 μs and 7 hnsecs
f2: 379 μs and 1 hnsec
May 17, 2016
On Tuesday, 17 May 2016 at 06:55:35 UTC, Alex wrote:
>
> import std.conv : to;
> import std.datetime;
> size_t aM = 5; size_t bM = 80;
> void f1() {auto io = iota(aM,bM);}
> void f2() {auto sl = testFunc(arr, aM ,bM);}
> auto r = benchmark!(f1, f2)(100_000);
> auto f0Result = to!Duration(r[0]); // time f1 took to run 10,000 times
> auto f1Result = to!Duration(r[1]); // time f2 took to run 10,000 times
> writeln("f1: ", f0Result);
> writeln("f2: ", f1Result);
>
> with dmd test44.d -release
> the results are:
> f1: 692 μs and 7 hnsecs
> f2: 379 μs and 1 hnsec

testFunc is the getSlice method... sorry... and the functions are run 100000 times
May 17, 2016
On Tuesday, 17 May 2016 at 06:55:35 UTC, Alex wrote:
> with dmd test44.d -release
> the results are:

You may want to pass '-O -inline' as well. -O enables general optimizations, -inline enables function inlining.

-release is for disabling bounds checks, invariants, asserts..

The -debug and -release switches influence the language's behavior. -O and -inline are optimization switches and should not change the behavior of your program, codegen bugs aside ^^

Additionally, some people recommend never using -release. It depends on that type of program you're writing, but the performance gain is often not worth the loss in safety. Think of the number of exploits enabled by C's lack of bounds checking.
May 17, 2016
On Tuesday, 17 May 2016 at 08:16:15 UTC, Rene Zwanenburg wrote:
> On Tuesday, 17 May 2016 at 06:55:35 UTC, Alex wrote:
>> with dmd test44.d -release
>> the results are:
>
> You may want to pass '-O -inline' as well. -O enables general optimizations, -inline enables function inlining.
>
> -release is for disabling bounds checks, invariants, asserts..
>
> The -debug and -release switches influence the language's behavior. -O and -inline are optimization switches and should not change the behavior of your program, codegen bugs aside ^^
>
> Additionally, some people recommend never using -release. It depends on that type of program you're writing, but the performance gain is often not worth the loss in safety. Think of the number of exploits enabled by C's lack of bounds checking.

ok... now the speed results are exact the same...
so...
besides
void*, ubyte*, a pointer to a strange, not constructible struct, I could take a iota too...


May 17, 2016
On Tuesday, 17 May 2016 at 08:45:44 UTC, Alex wrote:
> so...
> besides
> void*, ubyte*, a pointer to a strange, not constructible struct, I could take a iota too...

a comment on my own:
even every type of the above mentioned is possible, there are slightly differences between them:
1. As I don't want to be able to instantiate the type itself, I would like to drop ubyte*.
2. If I want to be able to slice a iota, I have to initialize it with the last number. But the object, which stores the pointer does not need to know anything about this number. So, I rather would not like to pass this number only for being able to instantiate the iota struct.

So this leave me again with the void* and a pointer to a strange, not constructible struct...