Re: how to benchmark pure functions?

2022-10-28 Thread ab via Digitalmars-d-learn

On Thursday, 27 October 2022 at 17:17:01 UTC, ab wrote:

Hi,

when trying to compare different implementations of the 
optimized builds of a pure function using benchmark from 
std.datetime.stopwatch, I get times equal to zero, I suppose 
because the functions are not executed as they do not have side 
effects.


The same happens with the example from the documentation:
https://dlang.org/library/std/datetime/stopwatch/benchmark.html

How can I prevent the compiler from removing the code I want to 
measure? Is there some utility in the standard library or 
pragma that I should use?


Thanks

AB


Thanks to H.S. Teoh and Dennis for the suggestions, they both 
work. I like the empty asm block a bit more because it is less 
invasive, but it only works with ldc.


@Imperatorn see Dennis code for an example. 
std.datetime.benchmark works, but at high optimization level 
(-O2, -O3) the loop can be removed and the time brought down to 
0hnsec. E.g. try "ldc2 -O3 -run dennis.d".


AB


how to benchmark pure functions?

2022-10-27 Thread ab via Digitalmars-d-learn

Hi,

when trying to compare different implementations of the optimized 
builds of a pure function using benchmark from 
std.datetime.stopwatch, I get times equal to zero, I suppose 
because the functions are not executed as they do not have side 
effects.


The same happens with the example from the documentation:
https://dlang.org/library/std/datetime/stopwatch/benchmark.html

How can I prevent the compiler from removing the code I want to 
measure? Is there some utility in the standard library or pragma 
that I should use?


Thanks

AB


Re: vibe.d / experience / feedback

2020-10-01 Thread ab via Digitalmars-d-learn
On Thursday, 1 October 2020 at 06:32:23 UTC, Robert M. Münch 
wrote:

3. Vibe can't handle GET & POST on the same URL...


we solved this one as well: fortunately (and: of course) vibe can 
handle this.


what lead us to believe otherwise, was that, unfortunately, one 
of the handlers crashed (effectively due to a `cast(JSONValue)` 
of a `Json.Undefined`), without any visible error output; and the 
only visible error was a "no route matches path" output from vibe.


sorry for the confusion.


Re: vibe.d / experience / feedback

2020-10-01 Thread ab via Digitalmars-d-learn

On Thursday, 1 October 2020 at 06:39:39 UTC, mipri wrote:
On Thursday, 1 October 2020 at 06:32:23 UTC, Robert M. Münch 
wrote:
5. One can't access the raw HTTP request body, things must be 
go through Vibe's JSON parser. To get access to the raw body, 
a lot of workarounds are necessary.


given an HTTPServerRequest req,
req.bodyReader.readAll for binary data and .readAllUTF8 for 
text.


thanks. that was tough to find from 
https://vibed.org/api/vibe.core.stream/InputStream (because it's 
located and thus documented in the helper module 
https://vibed.org/api/vibe.stream.operations/). a link from 
InputStream to vibe.stream.operations would be super-good.


Re: My RPN calculator code review?

2020-07-18 Thread AB via Digitalmars-d-learn

On Saturday, 18 July 2020 at 10:33:23 UTC, Anonymouse wrote:
I'm not happy about the looping and allocating replacements of 
spaced_args,


Actually, I got rid of that code entirely in order to support 
negative values:


-5 -6 *
== 30



My RPN calculator code review?

2020-07-17 Thread AB via Digitalmars-d-learn
Hello, inspired by the "Tiny RPN calculator" example seen on the 
dlang homepage, I wanted to create my own version.


I'd appreciate your opinions regarding style, mistakes/code 
smell/bad practice. Thank you.


import std.array;
import std.conv;
import std.stdio;

void main(string[] args)
{
if (args.length == 1)
{
writeln("usage examples:\n\t", args[0], " 5 3 + 2 
*\n\t", args[0],

" 12.1 11 /");
return;
}

immutable string valid_ops = "+-*/";
string spaced_args = args[1 .. $].join(" ");

// this is done to correctly handle "messy" inputs such 
as "5 3 2*+"

foreach (o; valid_ops)
{
spaced_args = spaced_args.replace(o, " " ~ o ~ " ");
}

real[] stack;

foreach (op; spaced_args.split)
{
LabeledSwitch:
switch (op) // operator or operand?
{
static foreach (o; valid_ops)
{
case [o]:
stack = stack[0 .. $ - 2] ~
mixin("stack[$ - 2]" ~ o ~ "stack[$ - 
1]");

break LabeledSwitch;
}
default:
// assume it's an operand, a real number
stack ~= to!real(op);
break;
}
}

writeln(stack);
}



Progress printing with threads?

2020-07-01 Thread AB via Digitalmars-d-learn
Hello. I am unsure how to proceed about printing progress in my 
program.


Suppose the program is processing a very big file and is 
iterating the file's bytes using a for loop. The processing takes 
several minutes and I want a progress percentage be printed every 
2 seconds in this manner:


Progress: 0.40%
Progress: 3.20%
Progress: 5.73%

Is it a good idea to std.concurrency.spawn a new thread and pass 
to it

cast(float)i * 100 / fileSize
somehow? If not, what's a better way to do this?

This example code shows my situation:

MmFile  input   = new MmFile(/* ... */);
ulong   fileSize= input.length;

for (ulong i = 0; i < fileSize; ++i)
{
// ...
}

Thanks in advance.



Re: Converting Lua source to D

2020-03-05 Thread AB via Digitalmars-d-learn

On Thursday, 5 March 2020 at 07:44:21 UTC, Jesse Phillips wrote:
I am making an attempt convert Lua to D. This is less about the 
conversion and more about exploring the tooling to make it 
happen.


I have chosen to do this file by file and attempting to start 
with linint. I wanted to make use of dpp, however I hit a 
segmentation fault and reduced dependency.


https://github.com/JesseKPhillips/lua/blob/dpp/init/linit.d

I wasn't able to get a core dump for debugging. Anyone willing 
to give some advice or solution? I have gone through a number 
of compilers and better.


I have implemented a build pipeline but didn't incorporate the 
D portion at this time.


I am only guessing, but I think the problem is line 87.
Arrays and slices in D contain a length field and thus do not 
need to be null terminated.
The foreach at line 96 iterates on all valid indices and thus in 
the last iteration you call luaL_requiref(L, null, null, 1).


Try changing

static const luaL_Reg[] loadedlibs = [
  ...
  {LUA_DBLIBNAME, _debug},
  {null, null}
];

to

static const luaL_Reg[] loadedlibs = [
  ...
  {LUA_DBLIBNAME, _debug}
];



Re: How to sum multidimensional arrays?

2020-03-01 Thread AB via Digitalmars-d-learn

On Saturday, 29 February 2020 at 19:04:12 UTC, p.shkadzko wrote:

On Friday, 28 February 2020 at 16:51:10 UTC, AB wrote:
On Thursday, 27 February 2020 at 14:15:26 UTC, p.shkadzko 
wrote:

[...]


Your Example with a minimal 2D array.


module test2;

import std.random : Xorshift, unpredictableSeed, uniform;
import std.range : generate, take, chunks;
import std.array : array;
import std.stdio : writeln;

struct Matrix(T)
{
 int rows;
 T[] data;
 alias data this;
 int cols() {return cast(int) data.length/rows;}
 this(int r, int c) { data=new int[r*c]; rows=r;}
 this(int r, int c, T[] d) {assert(r*c==data.length); data=d; 
rows=r; }


 auto opIndex(int r, int c) {return data[rows*c+r];}

}


Can you please explain what is the purpose of "alias data this" 
in your Matrix struct? As I remember "alias  this" is 
used for implicit type conversions but I don't see where "data" 
is converted.


Without "alias data this" the call

c[] = m1[] + m2[];

should be written as

c.data[] = m1.data[] + m2.data[];

With "alias data this" if some members of Matrix are not defined, 
but they are available for Matrix.data, the members of 
Matrix.data will be used.


It is more about names lookup rules than type conversions.








Re: How to sum multidimensional arrays?

2020-02-28 Thread AB via Digitalmars-d-learn

On Thursday, 27 February 2020 at 14:15:26 UTC, p.shkadzko wrote:
I'd like to sum 2D arrays. Let's create 2 random 2D arrays and 
sum them.


```
import std.random : Xorshift, unpredictableSeed, uniform;
import std.range : generate, take, chunks;
import std.array : array;

static T[][] rndMatrix(T)(T max, in int rows, in int cols)
{
Xorshift rnd;
rnd.seed(unpredictableSeed);
const amount = rows * cols;
return generate(() => uniform(0, max, 
rnd)).take(amount).array.chunks(cols).array;

}

void main() {
int[][] m1 = rndMatrix(10, 2, 3);
int[][] m2 = rndMatrix(10, 2, 3);

auto c = m1[] + m2[];
}
```



Maybe this is already clear, but it is important to highlight 
that 2D arrays and arrays of arrays are two different things.


int[][] is an array of arrays, for each outer index the element 
is an array that has its own allocated memory and length.


2D arrays are not provided by the language, but can be 
implemented by defining a type with the required operator 
overloads.


Using an array of arrays for a 1x1 matrix requires 10001 
allocations while a dedicated 2D array implementation needs only 
1;



Example of an array of arrays where the inner arrays have 
different lengths:



module test;
void main()
{
import std.stdio;

int[][] a;
a.length=3;

a[0]=[1,2,3];
a[1]=[3,4];
a[2]=[];
writeln(a);
}



Your Example with a minimal 2D array.



module test2;

import std.random : Xorshift, unpredictableSeed, uniform;
import std.range : generate, take, chunks;
import std.array : array;
import std.stdio : writeln;

struct Matrix(T)
{
 int rows;
 T[] data;
 alias data this;
 int cols() {return cast(int) data.length/rows;}
 this(int r, int c) { data=new int[r*c]; rows=r;}
 this(int r, int c, T[] d) {assert(r*c==data.length); data=d; 
rows=r; }


 auto opIndex(int r, int c) {return data[rows*c+r];}

}

auto rndMatrix(T)(T max, in int rows, in int cols)
{
Xorshift rnd;
rnd.seed(unpredictableSeed);
const amount = rows * cols;
return Matrix!T(rows,cols,generate(() => uniform(0, max, 
rnd)).take(amount).array);

}

void main() {
auto m1 = rndMatrix(10, 2, 3);
auto m2 = rndMatrix(10, 2, 3);

auto c = Matrix!int(2,3);
c[] = m1[] + m2[];
writeln(m1[1,2]);
writeln(m2[1,2]);
writeln(c[1,2]);
}


See https://dlang.org/spec/operatoroverloading.html#array-ops for 
a better overview of the required operators or mir.ndslice for an 
nD implementation.