Static array size?

2017-02-09 Thread Suliman via Digitalmars-d-learn

Docs says that:
"The total size of a static array cannot exceed 16Mb."
But when I am creation array of:
int [1000_000] x; // 1000_000 is equal ~ 0,95MB
app crush on start.

Should it's reserve this memory with guaranty? I mean that after 
app start it should take +0.95MB of RAM in task manager.


Re: Static array size?

2017-02-09 Thread Daniel Kozák via Digitalmars-d-learn
V Thu, 09 Feb 2017 11:22:28 +
Suliman via Digitalmars-d-learn 
napsáno:

> Docs says that:
> "The total size of a static array cannot exceed 16Mb."
> But when I am creation array of:
> int [1000_000] x; // 1000_000 is equal ~ 0,95MB
> app crush on start.
> 
> Should it's reserve this memory with guaranty? I mean that after 
> app start it should take +0.95MB of RAM in task manager.

First of all it is 4bytes * 1000_000 = 4000_000 bytes = 4kbyte, and it
should not crash, are you sure this is the reason why app crash?



Re: Static array size?

2017-02-09 Thread jkpl via Digitalmars-d-learn

On Thursday, 9 February 2017 at 11:22:28 UTC, Suliman wrote:

Docs says that:
"The total size of a static array cannot exceed 16Mb."
But when I am creation array of:
int [1000_000] x; // 1000_000 is equal ~ 0,95MB
app crush on start.

Should it's reserve this memory with guaranty? I mean that 
after app start it should take +0.95MB of RAM in task manager.


multiply by 4


Re: Static array size?

2017-02-09 Thread jkpl via Digitalmars-d-learn

On Thursday, 9 February 2017 at 12:16:26 UTC, jkpl wrote:

On Thursday, 9 February 2017 at 11:22:28 UTC, Suliman wrote:

Docs says that:
"The total size of a static array cannot exceed 16Mb."
But when I am creation array of:
int [1000_000] x; // 1000_000 is equal ~ 0,95MB
app crush on start.

Should it's reserve this memory with guaranty? I mean that 
after app start it should take +0.95MB of RAM in task manager.


multiply by 4


Also static array is not on the heap so take care to which column 
of the task manager you monitor.


Re: Static array size?

2017-02-09 Thread Daniel Kozak via Digitalmars-d-learn

On Thursday, 9 February 2017 at 12:13:36 UTC, Daniel Kozák wrote:

V Thu, 09 Feb 2017 11:22:28 +
Suliman via Digitalmars-d-learn 


napsáno:


Docs says that:
"The total size of a static array cannot exceed 16Mb."
But when I am creation array of:
int [1000_000] x; // 1000_000 is equal ~ 0,95MB
app crush on start.

Should it's reserve this memory with guaranty? I mean that 
after app start it should take +0.95MB of RAM in task manager.


First of all it is 4bytes * 1000_000 = 4000_000 bytes = 4kbyte, 
and it should not crash, are you sure this is the reason why 
app crash?


s/kbyte/megabyte




Re: Static array size?

2017-02-09 Thread Arek via Digitalmars-d-learn

On Thursday, 9 February 2017 at 11:22:28 UTC, Suliman wrote:

Docs says that:
"The total size of a static array cannot exceed 16Mb."
But when I am creation array of:
int [1000_000] x; // 1000_000 is equal ~ 0,95MB
app crush on start.

Should it's reserve this memory with guaranty? I mean that 
after app start it should take +0.95MB of RAM in task manager.


First of all, as others said it is 4 bytes * 100, what gives 
about 4MB.
Do you allocate this array on the stack? (local variables are 
created on the stack)
If yes, maybe you've exceeded the size of the stack. Declare the 
array out of the scope of any function and check again.
The size of the stack can be set in the linker 
(http://forum.dlang.org/post/mailman.766.1291253609.21107.digitalmar...@puremagic.com).





Factory using an alias template parameter to set a member of the new tool ?

2017-02-09 Thread jkpl via Digitalmars-d-learn

I'm looking for a better way to do this, if possible:

```
class Tool
{
string name;
}

T namedTool(alias Variable, T)()
{
T result = new T;
result.name = Variable.stringof;
return result;
}

void main()
{
Tool grep;
grep = namedTool!(grep,Tool);
assert(grep.name == "grep");
}
```

Ideally this would work like this:

```
Tool grep = namedTool!Tool;
assert(grep.name == "grep");
```

Possible ?


Re: Factory using an alias template parameter to set a member of the new tool ?

2017-02-09 Thread angel via Digitalmars-d-learn

On Thursday, 9 February 2017 at 13:30:07 UTC, jkpl wrote:

I'm looking for a better way to do this, if possible:

```
class Tool
{
string name;
}

T namedTool(alias Variable, T)()
{
T result = new T;
result.name = Variable.stringof;
return result;
}

void main()
{
Tool grep;
grep = namedTool!(grep,Tool);
assert(grep.name == "grep");
}
```

Ideally this would work like this:

```
Tool grep = namedTool!Tool;
assert(grep.name == "grep");
```

Possible ?


Sorry, but this does not make much sense to me ...
You expect "namedTool!Tool" to know that the name of the Tool 
must be set to "grep".
The expression evaluation proceeds from right to left, so at the 
time of analyzing "namedTool!Tool", the compiler knows nothing 
about "grep".
On the other hand, if you supplied the "grep" variable, the 
compiler could infer its type, like this:

```
...
auto namedTool(alias Variable)()
{
alias T = typeof(Variable);
T result = new T;
result.name = Variable.stringof;
return result;
}

void main()
{
Tool grep;
grep = namedTool!(grep);
assert(grep.name == "grep");
}
```


Re: Factory using an alias template parameter to set a member of the new tool ?

2017-02-09 Thread angel via Digitalmars-d-learn

On Thursday, 9 February 2017 at 14:39:41 UTC, angel wrote:

On Thursday, 9 February 2017 at 13:30:07 UTC, jkpl wrote:

I'm looking for a better way to do this, if possible:

```
class Tool
{
string name;
}

T namedTool(alias Variable, T)()
{
T result = new T;
result.name = Variable.stringof;
return result;
}

void main()
{
Tool grep;
grep = namedTool!(grep,Tool);
assert(grep.name == "grep");
}
```

Ideally this would work like this:

```
Tool grep = namedTool!Tool;
assert(grep.name == "grep");
```

Possible ?


Sorry, but this does not make much sense to me ...
You expect "namedTool!Tool" to know that the name of the Tool 
must be set to "grep".
The expression evaluation proceeds from right to left, so at 
the time of analyzing "namedTool!Tool", the compiler knows 
nothing about "grep".
On the other hand, if you supplied the "grep" variable, the 
compiler could infer its type, like this:

```
...
auto namedTool(alias Variable)()
{
alias T = typeof(Variable);
T result = new T;
result.name = Variable.stringof;
return result;
}

void main()
{
Tool grep;
grep = namedTool!(grep);
assert(grep.name == "grep");
}
```


Or actually, maybe this will suite your case better:
```
template namedTool(T, alias Variable)
{
enum namedTool = T.stringof ~ " " ~ Variable ~ " = new " ~ 
T.stringof ~ ";" ~

 Variable ~ ".name = \"" ~ Variable ~ "\";";
}

void main()
{
mixin(namedTool!(Tool, "grep"));
assert(grep.name == "grep");
}
```


Re: Factory using an alias template parameter to set a member of the new tool ?

2017-02-09 Thread jkpl via Digitalmars-d-learn

On Thursday, 9 February 2017 at 15:00:21 UTC, angel wrote:

On Thursday, 9 February 2017 at 14:39:41 UTC, angel wrote:

On Thursday, 9 February 2017 at 13:30:07 UTC, jkpl wrote:

I'm looking for a better way to do this, if possible:


Or actually, maybe this will suite your case better:
```
template namedTool(T, alias Variable)
{
enum namedTool = T.stringof ~ " " ~ Variable ~ " = new " ~ 
T.stringof ~ ";" ~

 Variable ~ ".name = \"" ~ Variable ~ "\";";
}

void main()
{
mixin(namedTool!(Tool, "grep"));
assert(grep.name == "grep");
}
```


Thanks for trying. I know that it doesn't make much sense but it 
would have been a cool sugar for the tool class.


Mixins are not good for me because of completion in the IDE.


Strange behaviour of rdmd vs. dmd concerning main function

2017-02-09 Thread berni via Digitalmars-d-learn

I've got two source files in two directories:

Common/common.d


module common;

import std.stdio;

int main(string[] args)
{
   Foo foo = cast(Foo)Object.factory("special.Bar");

   foo.do_something();

   return 0;
}

abstract class Foo {
   abstract void do_something();
}


Special/special.d


module special;

import std.stdio;
import common;

class Bar : Foo {
   override void do_something()
   {
   writeln("works");
   }
}


Now I try to run it with rdmd and dmd and get quite different 
results:



$> rdmd -ICommon Special/special.d
works
$> dmd -ICommon Special/special.d
/usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/Scrt1.o: In function 
`_start':
(.text+0x20): undefined reference to `main'
special.o:(.data.rel.ro+0x18): undefined reference to 
`_D6common12__ModuleInfoZ'
special.o:(.data._D7special3Bar7__ClassZ+0x50): undefined 
reference to `_D6common3Foo7__ClassZ'

collect2: error: ld returned 1 exit status
Error: linker exited with status 1


I encountered this, when I was curious if I can move the main 
function to a diffent module, because it will be the same in 
several modules anyway. When testing with rdmd, everything 
worked. Later, I found out, that with dmd it doesn't. (And with 
gdc and ldc2 it doesn't work too.)


For me, this looks like a bug in either rdmd or dmd. But maybe 
there is something about it that I do not understand.


Re: Strange behaviour of rdmd vs. dmd concerning main function

2017-02-09 Thread via Digitalmars-d-learn
On Thu, Feb 09, 2017 at 03:39:18PM +, berni via Digitalmars-d-learn wrote:
> Now I try to run it with rdmd and dmd and get quite different results:

dmd only compiles in the files you actually pass to it. rdmd
will try to find the required files automatically.

Since you didn't pass the file with the function to dmd, it knows
it exists, but leaves it out of the final link (it assumes it might
come from a library or something). That's why you see the error.

rdmd exists because it handles it more automatically.



Re: Strange behaviour of rdmd vs. dmd concerning main function

2017-02-09 Thread berni via Digitalmars-d-learn
dmd only compiles in the files you actually pass to it. rdmd 
will try to find the required files automatically.


Since you didn't pass the file with the function to dmd, it 
knows it exists, but leaves it out of the final link (it 
assumes it might come from a library or something). That's why 
you see the error.


Ah ok, I understand. So calling with "dmd Special/special.d 
Common/common.d" works.


But when I compile common.d to common.o (with dmd -c common.d) 
and remove common.d after that is there still a possibility to 
link? The obvious doesn't work:


$> dmd Special/special.d Common/common.o Special/special.d(4): 
Error: module common is in file 'common.d' which cannot be read

import path[0] = /usr/include/dmd/phobos
import path[1] = /usr/include/dmd/druntime/import




Re: Cross-compile with LDC

2017-02-09 Thread Joakim via Digitalmars-d-learn

On Wednesday, 8 February 2017 at 17:57:49 UTC, kinke wrote:

On Wednesday, 8 February 2017 at 17:21:03 UTC, Oleg B wrote:
If I understand correctly with vanilla LDC I can't 
cross-compiling from host linux-x86_64, but with your patch I 
can. Right?


Right. Joakim Noah has worked on LDC for Android and as far as 
I know provides some prebuilt compilers, a native one and a 
cross-compiler (Linux x86_64 host) including that patch.
There's also a pre-built Windows -> ARM cross-compiler; see 
http://forum.dlang.org/thread/xzzzfvahuwvgsluli...@forum.dlang.org and more ARM-related threads in our subforum.


That's not really a Windows build of ldc, he just used the new 
linux support in Windows 10.  There is a build of ldc 1.1.0 for 
native linux/ARM, if you want to compile D code on the ARM device 
itself:


https://github.com/ldc-developers/ldc/releases/tag/v1.1.0

If not, it's pretty straight forward to build a cross-compiler 
for ARM, take a look at my patches and instructions for Android:


https://github.com/joakim-noah/android/releases

If I use your patch must I use in my programs only double or I 
can stay real in existing code?


Don't worry, the reals can stay.


The patch will make reals the same as double, ie they're all 
64-bit, so it is irrelevant which one you use.  If you're writing 
cross-platform code and care about that difference on other 
platforms, you may need to check for it.  Take a look at std.math 
for examples of this, where it checks the length of the mantissa 
sometimes for reals.


fix for sample mandelbrot code from documentation -- latest gdc has no lockingBinaryWriter

2017-02-09 Thread Oasiq via Digitalmars-d-learn

Hi,

I was trying to run the example code from

https://dlang.org/phobos/std_stdio.html#.File.lockingBinaryWriter

which is very short, as follows.

===

import std.algorithm, std.range, std.stdio;
void main()
{
enum size = 500;
writef("P5\n%d %d %d\n", size, size, ubyte.max);

iota(-1, 3, 2.0/size).map!(y =>
iota(-1.5, 0.5, 2.0/size).map!(x =>
cast(ubyte)(1+
recurrence!((a, n) => x + y*1i + a[n-1]^^2)(0+0i)
.take(ubyte.max)
.countUntil!(z => z.re^^2 + z.im^^2 > 4))
)
)
.copy(stdout.lockingBinaryWriter);
}

===

Unfortunately, my compiler fails with

$ gdc -Wall -o m1 m1.d m2.d:14:17: error: no property 
'lockingBinaryWriter' for type 'File'

 .copy(stdout.lockingBinaryWriter);


It looks like the latest in the repository isn't recent enough, 
since the source code online to stdio.d on github has 
lockingBinaryWriter in it, but my copy installed via ubuntu apt 
does not.


I tried


$ gdc --version


and got


gdc (Ubuntu 6.2.0-5ubuntu12) 6.2.0 20161005


but that doesn't say what version the frontend compiler or 
standard library is.  After searching on the web, I found a 
pragma that I added to the file



pragma(msg, __VERSION__);


which gave the version "2068L" when I compiled it. According to

https://gdcproject.org/downloads

the latest gdc(1) uses the DMDFE version 2.068.2 which isn't new 
enough I guess, since the DMD version appears to be 2.073.0 which 
includes lockingBinaryWriter.


This fixes the problem:

===

import std.range, std.array, std.stdio;

void main()
{
auto buf = appender!(ubyte[])();
enum size = 500;
writef("P5\n%d %d %d\n", size, size, ubyte.max);
iota(-1, 3, 2.0/size).map!(y =>
iota(-1.5, 0.5, 2.0/size).map!(x =>
cast(ubyte)(1+
recurrence!((a, n) => x + y*1i + a[n-1]^^2)(0+0i)
.take(ubyte.max)
.countUntil!(z => z.re^^2 + z.im^^2 > 4))
)
)
.copy(buf);
stdout.rawWrite(buf.data);
}

===

And running it


$ gdc -Wall -o m2 m2.d && ./m1 > aaa.pnm && display aaa.pnm


produces the expected result.

I'm posting this in case anyone else encounters this problem.  I 
don't know D at all, and perhaps this will save someone else from 
some head scratching and going down output iterator rabbit holes.


Best regards,

Oasiq.


Can this implementation of Damm algorithm be optimized?

2017-02-09 Thread Nestor via Digitalmars-d-learn

Hi,

I was trying to port C code from the article in Wikiversity [1] 
to D, but I'm not sure this implementation is the most efficient 
way to do it in D, so suggestions to optimize it are welcome:


import std.stdio;

static immutable char[] QG10Matrix =
  "03175986427092154863420687135917509834266123045978" ~
  "36742095815869720134894536201794386172052581436790";

char checkDigit(string str) {
  char tmpdigit = '0';
  foreach(chr; str) tmpdigit = QG10Matrix[(chr - '0') + (tmpdigit 
- '0') * 10];

  return tmpdigit;
}

enum {
  EXIT_SUCCESS = 0,
  EXIT_FAILURE = 1,
}

int main(string[] args) {
  scope(failure) {
writeln("Invalid arguments. You must pass a number.");
return EXIT_FAILURE;
  }
  assert(args.length == 2);
  char digit = checkDigit(args[1]);
  if(digit == '0') writefln("%s is a valid number.", args[1]);
  else {
writefln("%s is not a valid number (but it would be, 
appending digit %s).",

  args[1], digit);
  }

  return EXIT_SUCCESS;
}

[1] https://en.wikiversity.org/wiki/Damm_algorithm


Re: Can this implementation of Damm algorithm be optimized?

2017-02-09 Thread Cym13 via Digitalmars-d-learn

On Thursday, 9 February 2017 at 17:36:11 UTC, Nestor wrote:

Hi,

I was trying to port C code from the article in Wikiversity [1] 
to D, but I'm not sure this implementation is the most 
efficient way to do it in D, so suggestions to optimize it are 
welcome:


import std.stdio;

static immutable char[] QG10Matrix =
  "03175986427092154863420687135917509834266123045978" ~
  "36742095815869720134894536201794386172052581436790";

char checkDigit(string str) {
  char tmpdigit = '0';
  foreach(chr; str) tmpdigit = QG10Matrix[(chr - '0') + 
(tmpdigit - '0') * 10];

  return tmpdigit;
}

enum {
  EXIT_SUCCESS = 0,
  EXIT_FAILURE = 1,
}

int main(string[] args) {
  scope(failure) {
writeln("Invalid arguments. You must pass a number.");
return EXIT_FAILURE;
  }
  assert(args.length == 2);
  char digit = checkDigit(args[1]);
  if(digit == '0') writefln("%s is a valid number.", args[1]);
  else {
writefln("%s is not a valid number (but it would be, 
appending digit %s).",

  args[1], digit);
  }

  return EXIT_SUCCESS;
}

[1] https://en.wikiversity.org/wiki/Damm_algorithm


I can't see how to make it more efficient than it is (aside from 
finding a better algorithm which isn't a language concern). You 
are using C style and will get the same machine code as if you'd 
written it with C. The only difference would be boundchecking 
that you can disable by using the -boundscheck=off compiler 
switch.


By the way note that you can use the -profile switch to see where 
the bottlenecks are, in your case writting the result to stdout 
is *by far* what takes the most time (and I'm quite certain the 
bottleneck is the same in the C version for it's a fact that I/O 
is slow).


Re: Can this implementation of Damm algorithm be optimized?

2017-02-09 Thread Era Scarecrow via Digitalmars-d-learn

On Thursday, 9 February 2017 at 17:36:11 UTC, Nestor wrote:
I was trying to port C code from the article in Wikiversity [1] 
to D, but I'm not sure this implementation is the most 
efficient way to do it in D, so suggestions to optimize it are 
welcome:


import std.stdio;

static immutable char[] QG10Matrix =
  "03175986427092154863420687135917509834266123045978" ~
  "36742095815869720134894536201794386172052581436790";

char checkDigit(string str) {
  char tmpdigit = '0';
  foreach(chr; str) tmpdigit = QG10Matrix[(chr - '0') + 
(tmpdigit - '0') * 10];

  return tmpdigit;
}


Well one thing is you can probably reduce them from chars to just 
bytes, instead of having to subtract you can instead add at the 
end. Although unless you're working with a VERY large input you 
won't see a difference.


Actually since you're also multiplying by 10, you can incorporate 
that in the table too... (although a mixin might be better for 
the conversion than by hand)



 static immutable char[] QG10Matrix = [
00,30,10,70,50,90,80,60,40,20,
70,00,90,20,10,50,40,80,60,30,
40,20,00,60,80,70,10,30,50,90,
10,70,50,00,90,80,30,40,20,60,
60,10,20,30,00,40,50,90,70,80,
30,60,70,40,20,00,90,50,80,10,
50,80,60,90,70,20,00,10,30,40,
80,90,40,50,30,60,20,00,10,70,
90,40,30,80,60,10,70,20,00,50,
20,50,80,10,40,30,60,70,90,00];

 char checkDigit(string str) {
   char tmpdigit = 0;
   foreach(chr; str) tmpdigit = QG10Matrix[(chr - '0') +
 tmpdigit];
   return (tmpdigit/10) + '0';
 }


Re: Strange behaviour of rdmd vs. dmd concerning main function

2017-02-09 Thread Daniel Kozak via Digitalmars-d-learn

Dne 9.2.2017 v 17:20 berni via Digitalmars-d-learn napsal(a):

dmd only compiles in the files you actually pass to it. rdmd will try 
to find the required files automatically.


Since you didn't pass the file with the function to dmd, it knows it 
exists, but leaves it out of the final link (it assumes it might come 
from a library or something). That's why you see the error.


Ah ok, I understand. So calling with "dmd Special/special.d 
Common/common.d" works.


But when I compile common.d to common.o (with dmd -c common.d) and 
remove common.d after that is there still a possibility to link? The 
obvious doesn't work:


$> dmd Special/special.d Common/common.o Special/special.d(4): Error: 
module common is in file 'common.d' which cannot be read

import path[0] = /usr/include/dmd/phobos
import path[1] = /usr/include/dmd/druntime/import



Thats ok too, you still need to add -ICommon
dmd -ICommon Special/special.d Common/common.o


Re: Can this implementation of Damm algorithm be optimized?

2017-02-09 Thread Nestor via Digitalmars-d-learn

On Thursday, 9 February 2017 at 18:34:30 UTC, Era Scarecrow wrote:

On Thursday, 9 February 2017 at 17:36:11 UTC, Nestor wrote:
I was trying to port C code from the article in Wikiversity 
[1] to D, but I'm not sure this implementation is the most 
efficient way to do it in D, so suggestions to optimize it are 
welcome:


import std.stdio;

static immutable char[] QG10Matrix =
  "03175986427092154863420687135917509834266123045978" ~
  "36742095815869720134894536201794386172052581436790";

char checkDigit(string str) {
  char tmpdigit = '0';
  foreach(chr; str) tmpdigit = QG10Matrix[(chr - '0') + 
(tmpdigit - '0') * 10];

  return tmpdigit;
}


Well one thing is you can probably reduce them from chars to 
just bytes, instead of having to subtract you can instead add 
at the end. Although unless you're working with a VERY large 
input you won't see a difference.


Actually since you're also multiplying by 10, you can 
incorporate that in the table too... (although a mixin might be 
better for the conversion than by hand)



 static immutable char[] QG10Matrix = [
00,30,10,70,50,90,80,60,40,20,
70,00,90,20,10,50,40,80,60,30,
40,20,00,60,80,70,10,30,50,90,
10,70,50,00,90,80,30,40,20,60,
60,10,20,30,00,40,50,90,70,80,
30,60,70,40,20,00,90,50,80,10,
50,80,60,90,70,20,00,10,30,40,
80,90,40,50,30,60,20,00,10,70,
90,40,30,80,60,10,70,20,00,50,
20,50,80,10,40,30,60,70,90,00];

 char checkDigit(string str) {
   char tmpdigit = 0;
   foreach(chr; str) tmpdigit = QG10Matrix[(chr - '0') +
 tmpdigit];
   return (tmpdigit/10) + '0';
 }




OK I changed the approach using a multidimensional array for the 
matrix so I could ditch arithmetic operations altogether, but 
curiously after measuring a few thousand runs of both 
implementations through avgtime, I see no noticeable difference. 
Why?


import std.stdio;

static immutable ubyte[][] QG10Matrix = [
  [0,3,1,7,5,9,8,6,4,2],[7,0,9,2,1,5,4,8,6,3],
  [4,2,0,6,8,7,1,3,5,9],[1,7,5,0,9,8,3,4,2,6],
  [6,1,2,3,0,4,5,9,7,8],[3,6,7,4,2,0,9,5,8,1],
  [5,8,6,9,7,2,0,1,3,4],[8,9,4,5,3,6,2,0,1,7],
  [9,4,3,8,6,1,7,2,0,5],[2,5,8,1,4,3,6,7,9,0],
];

static int charToInt(char chr) {
  scope(failure) return -1;
  return cast(int)(chr - '0');
}

ubyte checkDigit(string str) {
  ubyte tmpdigit;
  foreach(chr; str) tmpdigit = 
QG10Matrix[tmpdigit][charToInt(chr)];

  return tmpdigit;
}

enum {
  EXIT_SUCCESS = 0,
  EXIT_FAILURE = 1,
}

int main(string[] args) {
  scope(failure) {
writeln("Invalid arguments. You must pass a number.");
return EXIT_FAILURE;
  }
  assert(args.length == 2);
  ubyte digit = checkDigit(args[1]);
  if(digit == 0) writefln("%s is a valid number.", args[1]);
  else {
writefln("%s is not a valid number (but it would be, 
appending digit %s).",

  args[1], digit);
  }

  return EXIT_SUCCESS;
}



Re: Can this implementation of Damm algorithm be optimized?

2017-02-09 Thread Nestor via Digitalmars-d-learn

On Thursday, 9 February 2017 at 18:34:30 UTC, Era Scarecrow wrote:

...
Actually since you're also multiplying by 10, you can 
incorporate that in the table too...


I forgot to comment that what is multiplied by ten is not the 
value but the starting position in the array (a way to emulate a 
matrix), but anyway see my comments in previous post.


Re: Strange behaviour of rdmd vs. dmd concerning main function

2017-02-09 Thread berni via Digitalmars-d-learn

On Thursday, 9 February 2017 at 19:10:55 UTC, Daniel Kozak wrote:

Dne 9.2.2017 v 17:20 berni via Digitalmars-d-learn napsal(a):


[...]


Ah ok, I understand. So calling with "dmd Special/special.d 
Common/common.d" works.


But when I compile common.d to common.o (with dmd -c common.d) 
and remove common.d after that is there still a possibility to 
link? The obvious doesn't work:



[...]



Thats ok too, you still need to add -ICommon
dmd -ICommon Special/special.d Common/common.o


Doesn't work here:


$> dmd -ICommon Special/special.d Common/common.o
Special/special.d(4): Error: module common is in file 'common.d' 
which cannot be read

import path[0] = Common
import path[1] = /usr/include/dmd/phobos
import path[2] = /usr/include/dmd/druntime/import


Getting familiar with std.process

2017-02-09 Thread jmh530 via Digitalmars-d-learn
I haven't used std.process before and am trying to play around 
with it.


In the code below, the first file writes some text to an output 
file. My goal is to be able to read what is written to that file 
without creating the file itself. I'm not sure it's possible, but 
the second file is my attempt.


The second file compiles the first (for the sake of simplicity), 
then creates a pipe with program it compiles, piping the result 
to stdout, then it saves the result to an output string, which I 
then print (or potentially manipulate in some other way in the 
future). But it doesn't print anything (why I'm posting here).


I think the issue is that create_file doesn't write to stdout, it 
writes to file. Other than reading the file and then deleting it, 
I don't know what else to try.


//create_file.d

import std.stdio : toFile;

void main()
{
toFile("test", "output.txt");
}

//read_file.d
//read_file.d

import std.process;
import std.stdio;

void main()
{
auto command1 = execute(["dmd", "create_file.d"]);
//auto command2 = execute(["create_file.exe"]);

auto pipes = pipeProcess("create_file.exe", Redirect.stdout);
scope(exit) wait(pipes.pid);

foreach (line; pipes.stdout.byLine) writeln(line);
}


Re: Can this implementation of Damm algorithm be optimized?

2017-02-09 Thread Daniel Kozak via Digitalmars-d-learn

Dne 9.2.2017 v 20:39 Nestor via Digitalmars-d-learn napsal(a):


On Thursday, 9 February 2017 at 18:34:30 UTC, Era Scarecrow wrote:

On Thursday, 9 February 2017 at 17:36:11 UTC, Nestor wrote:
I was trying to port C code from the article in Wikiversity [1] to 
D, but I'm not sure this implementation is the most efficient way to 
do it in D, so suggestions to optimize it are welcome:


import std.stdio;

static immutable char[] QG10Matrix =
  "03175986427092154863420687135917509834266123045978" ~
  "36742095815869720134894536201794386172052581436790";

char checkDigit(string str) {
  char tmpdigit = '0';
  foreach(chr; str) tmpdigit = QG10Matrix[(chr - '0') + (tmpdigit - 
'0') * 10];

  return tmpdigit;
}


Well one thing is you can probably reduce them from chars to just 
bytes, instead of having to subtract you can instead add at the end. 
Although unless you're working with a VERY large input you won't see 
a difference.


Actually since you're also multiplying by 10, you can incorporate 
that in the table too... (although a mixin might be better for the 
conversion than by hand)



 static immutable char[] QG10Matrix = [
00,30,10,70,50,90,80,60,40,20,
70,00,90,20,10,50,40,80,60,30,
40,20,00,60,80,70,10,30,50,90,
10,70,50,00,90,80,30,40,20,60,
60,10,20,30,00,40,50,90,70,80,
30,60,70,40,20,00,90,50,80,10,
50,80,60,90,70,20,00,10,30,40,
80,90,40,50,30,60,20,00,10,70,
90,40,30,80,60,10,70,20,00,50,
20,50,80,10,40,30,60,70,90,00];

 char checkDigit(string str) {
   char tmpdigit = 0;
   foreach(chr; str) tmpdigit = QG10Matrix[(chr - '0') +
 tmpdigit];
   return (tmpdigit/10) + '0';
 }




OK I changed the approach using a multidimensional array for the 
matrix so I could ditch arithmetic operations altogether, but 
curiously after measuring a few thousand runs of both implementations 
through avgtime, I see no noticeable difference. Why?


import std.stdio;

static immutable ubyte[][] QG10Matrix = [
  [0,3,1,7,5,9,8,6,4,2],[7,0,9,2,1,5,4,8,6,3],
  [4,2,0,6,8,7,1,3,5,9],[1,7,5,0,9,8,3,4,2,6],
  [6,1,2,3,0,4,5,9,7,8],[3,6,7,4,2,0,9,5,8,1],
  [5,8,6,9,7,2,0,1,3,4],[8,9,4,5,3,6,2,0,1,7],
  [9,4,3,8,6,1,7,2,0,5],[2,5,8,1,4,3,6,7,9,0],
];

static int charToInt(char chr) {
  scope(failure) return -1;
  return cast(int)(chr - '0');
}

ubyte checkDigit(string str) {
  ubyte tmpdigit;
  foreach(chr; str) tmpdigit = QG10Matrix[tmpdigit][charToInt(chr)];
  return tmpdigit;
}

enum {
  EXIT_SUCCESS = 0,
  EXIT_FAILURE = 1,
}

int main(string[] args) {
  scope(failure) {
writeln("Invalid arguments. You must pass a number.");
return EXIT_FAILURE;
  }
  assert(args.length == 2);
  ubyte digit = checkDigit(args[1]);
  if(digit == 0) writefln("%s is a valid number.", args[1]);
  else {
writefln("%s is not a valid number (but it would be, appending 
digit %s).",

  args[1], digit);
  }

  return EXIT_SUCCESS;
}


Maybe you can try use static array instead of dynamic
static immutable ubyte[10][10] QG10Matrix = ...


Re: Strange behaviour of rdmd vs. dmd concerning main function

2017-02-09 Thread Daniel Kozak via Digitalmars-d-learn

Dne 9.2.2017 v 21:10 berni via Digitalmars-d-learn napsal(a):


On Thursday, 9 February 2017 at 19:10:55 UTC, Daniel Kozak wrote:

Dne 9.2.2017 v 17:20 berni via Digitalmars-d-learn napsal(a):


[...]


Ah ok, I understand. So calling with "dmd Special/special.d 
Common/common.d" works.


But when I compile common.d to common.o (with dmd -c common.d) and 
remove common.d after that is there still a possibility to link? The 
obvious doesn't work:



[...]



Thats ok too, you still need to add -ICommon
dmd -ICommon Special/special.d Common/common.o


Doesn't work here:


$> dmd -ICommon Special/special.d Common/common.o
Special/special.d(4): Error: module common is in file 'common.d' 
which cannot be read

import path[0] = Common
import path[1] = /usr/include/dmd/phobos
import path[2] = /usr/include/dmd/druntime/import

Which version of dmd you have?
It should work, you probably do something wrong, I have use your example 
files so do you change them somehow?


Re: Can this implementation of Damm algorithm be optimized?

2017-02-09 Thread Cym13 via Digitalmars-d-learn

On Thursday, 9 February 2017 at 19:39:49 UTC, Nestor wrote:
On Thursday, 9 February 2017 at 18:34:30 UTC, Era Scarecrow 
wrote:

On Thursday, 9 February 2017 at 17:36:11 UTC, Nestor wrote:
I was trying to port C code from the article in Wikiversity 
[1] to D, but I'm not sure this implementation is the most 
efficient way to do it in D, so suggestions to optimize it 
are welcome:


import std.stdio;

static immutable char[] QG10Matrix =
  "03175986427092154863420687135917509834266123045978" ~
  "36742095815869720134894536201794386172052581436790";

char checkDigit(string str) {
  char tmpdigit = '0';
  foreach(chr; str) tmpdigit = QG10Matrix[(chr - '0') + 
(tmpdigit - '0') * 10];

  return tmpdigit;
}


Well one thing is you can probably reduce them from chars to 
just bytes, instead of having to subtract you can instead add 
at the end. Although unless you're working with a VERY large 
input you won't see a difference.


Actually since you're also multiplying by 10, you can 
incorporate that in the table too... (although a mixin might 
be better for the conversion than by hand)



 static immutable char[] QG10Matrix = [
00,30,10,70,50,90,80,60,40,20,
70,00,90,20,10,50,40,80,60,30,
40,20,00,60,80,70,10,30,50,90,
10,70,50,00,90,80,30,40,20,60,
60,10,20,30,00,40,50,90,70,80,
30,60,70,40,20,00,90,50,80,10,
50,80,60,90,70,20,00,10,30,40,
80,90,40,50,30,60,20,00,10,70,
90,40,30,80,60,10,70,20,00,50,
20,50,80,10,40,30,60,70,90,00];

 char checkDigit(string str) {
   char tmpdigit = 0;
   foreach(chr; str) tmpdigit = QG10Matrix[(chr - '0') +
 tmpdigit];
   return (tmpdigit/10) + '0';
 }




OK I changed the approach using a multidimensional array for 
the matrix so I could ditch arithmetic operations altogether, 
but curiously after measuring a few thousand runs of both 
implementations through avgtime, I see no noticeable 
difference. Why?


import std.stdio;

static immutable ubyte[][] QG10Matrix = [
  [0,3,1,7,5,9,8,6,4,2],[7,0,9,2,1,5,4,8,6,3],
  [4,2,0,6,8,7,1,3,5,9],[1,7,5,0,9,8,3,4,2,6],
  [6,1,2,3,0,4,5,9,7,8],[3,6,7,4,2,0,9,5,8,1],
  [5,8,6,9,7,2,0,1,3,4],[8,9,4,5,3,6,2,0,1,7],
  [9,4,3,8,6,1,7,2,0,5],[2,5,8,1,4,3,6,7,9,0],
];

static int charToInt(char chr) {
  scope(failure) return -1;
  return cast(int)(chr - '0');
}

ubyte checkDigit(string str) {
  ubyte tmpdigit;
  foreach(chr; str) tmpdigit = 
QG10Matrix[tmpdigit][charToInt(chr)];

  return tmpdigit;
}

enum {
  EXIT_SUCCESS = 0,
  EXIT_FAILURE = 1,
}

int main(string[] args) {
  scope(failure) {
writeln("Invalid arguments. You must pass a number.");
return EXIT_FAILURE;
  }
  assert(args.length == 2);
  ubyte digit = checkDigit(args[1]);
  if(digit == 0) writefln("%s is a valid number.", args[1]);
  else {
writefln("%s is not a valid number (but it would be, 
appending digit %s).",

  args[1], digit);
  }

  return EXIT_SUCCESS;
}


The question is, why do you expect it to be noticably faster? On 
modern hardware it the optimizations are such that so little a 
change in code is very hard to link to a difference in running 
time. If you really want to show one the following code does the 
benchmark the right way (ie: using a very long input, tens of 
thousands of runs, and avoiding I/O and load time of the program 
to compare the bare function implementations):


import std.conv;
import std.stdio;
import std.range;
import std.array;
import std.algorithm;

string testcase;

static immutable char[] QG10MatrixOne =
  "03175986427092154863420687135917509834266123045978" ~
  "36742095815869720134894536201794386172052581436790";

char checkDigitOne(string str) {
  char tmpdigit = 0;
  foreach(chr; str) tmpdigit = QG10MatrixOne[(chr - '0') + 
(tmpdigit - '0') * 10];

  return tmpdigit;
}

void testCheckDigitOne() {
checkDigitTwo(testcase);
}

static immutable ubyte[][] QG10MatrixTwo = [
  [0,3,1,7,5,9,8,6,4,2],[7,0,9,2,1,5,4,8,6,3],
  [4,2,0,6,8,7,1,3,5,9],[1,7,5,0,9,8,3,4,2,6],
  [6,1,2,3,0,4,5,9,7,8],[3,6,7,4,2,0,9,5,8,1],
  [5,8,6,9,7,2,0,1,3,4],[8,9,4,5,3,6,2,0,1,7],
  [9,4,3,8,6,1,7,2,0,5],[2,5,8,1,4,3,6,7,9,0],
];

static int charToInt(char chr) {
  scope(failure) return -1;
  return cast(int)(chr - '0');
}

ubyte checkDigitTwo(string str) {
  ubyte tmpdigit;
  foreach(chr; str) {
  tmpdigit = QG10MatrixTwo[tmpdigit][charToInt(chr)];
  }
  return tmpdigit;
}

void testCheckDigitTwo() {
checkDigitTwo(testcase);
}

void main(string[] args) {
  testcase = 
iota(10).cycle.take(10).map!(to!string).array.join;


  import std.datetime: benchmark;
  benchmark!(testCheckDigitOne, 
testCheckDigitTwo)(1).each!writeln;

}


Yet on my machine I have the following times (note that the time 
itself depends on my hardware, what's important is the 
difference):


TickDuration(15785255852)
TickDuration(15784826803)

So it seems that the first version is slower than the second one, 
but by so little that it's hard to link to the actual 
implementation. If anything it shows the futility of su

Re: Can this implementation of Damm algorithm be optimized?

2017-02-09 Thread Nestor via Digitalmars-d-learn

On Thursday, 9 February 2017 at 20:46:06 UTC, Daniel Kozak wrote:

Maybe you can try use static array instead of dynamic
static immutable ubyte[10][10] QG10Matrix = ...


I shaved it to this to discard unneccessary time-consuming 
functions:


static immutable ubyte[10][10] QG10Matrix = [
  [0,3,1,7,5,9,8,6,4,2],[7,0,9,2,1,5,4,8,6,3],
  [4,2,0,6,8,7,1,3,5,9],[1,7,5,0,9,8,3,4,2,6],
  [6,1,2,3,0,4,5,9,7,8],[3,6,7,4,2,0,9,5,8,1],
  [5,8,6,9,7,2,0,1,3,4],[8,9,4,5,3,6,2,0,1,7],
  [9,4,3,8,6,1,7,2,0,5],[2,5,8,1,4,3,6,7,9,0],
];

static immutable string number =
  
"0123456789012345678901234567890123456789012345678901234567890123456789";


static int charToInt(char chr) {
  return ((chr >= '0') || (chr <= '9')) ? cast(int)(chr - '0') : 
-1;

}

ubyte checkDigit(string str) {
  ubyte tmpdigit;
  foreach(chr; str) tmpdigit = 
QG10Matrix[tmpdigit][charToInt(chr)];

  return tmpdigit;
}

void main() {
  auto digit = checkDigit(number);
}

I even tried making checkDigit static, but surprisingly this 
increased average execution time by 1ms.


Anyway, the previopus version (modified to benefit from a little 
optimization too) is almost as performant, even though it 
includes multiplication and sum:


static immutable char[] QG10Matrix =
  "03175986427092154863420687135917509834266123045978" ~
  "36742095815869720134894536201794386172052581436790";

static immutable string number =
  
"0123456789012345678901234567890123456789012345678901234567890123456789";


static int charToInt(char chr) {
  return ((chr >= '0') || (chr <= '9')) ? cast(int)(chr - '0') : 
-1;

}

char checkDigit(string str) {
  char tmpdigit = '0';
  foreach(chr; str) tmpdigit =
QG10Matrix[charToInt(chr) + (charToInt(tmpdigit) * 10)];
  return tmpdigit;
}

void main() {
  auto digit = checkDigit(number);
}

I compiled both with -inline -noboundscheck -release and the 
multidimensional array version does perform 1ms faster for a 
couple hundred runs, but I expected the difference to be much 
more noticeable.


Any idea of what might be happening here?


Re: Getting familiar with std.process

2017-02-09 Thread Ali Çehreli via Digitalmars-d-learn

On 02/09/2017 12:44 PM, jmh530 wrote:

> I think the issue is that create_file doesn't write to stdout, it writes
> to file.

Correct. Pipe works by piping the standard input/output streams.

> Other than reading the file and then deleting it, I don't know
> what else to try.

create_file must write to its stdout.

Ali



Re: Can this implementation of Damm algorithm be optimized?

2017-02-09 Thread Daniel Kozak via Digitalmars-d-learn

Dne 9.2.2017 v 22:29 Nestor via Digitalmars-d-learn napsal(a):


On Thursday, 9 February 2017 at 20:46:06 UTC, Daniel Kozak wrote:

Maybe you can try use static array instead of dynamic
static immutable ubyte[10][10] QG10Matrix = ...


I shaved it to this to discard unneccessary time-consuming functions:

static immutable ubyte[10][10] QG10Matrix = [
  [0,3,1,7,5,9,8,6,4,2],[7,0,9,2,1,5,4,8,6,3],
  [4,2,0,6,8,7,1,3,5,9],[1,7,5,0,9,8,3,4,2,6],
  [6,1,2,3,0,4,5,9,7,8],[3,6,7,4,2,0,9,5,8,1],
  [5,8,6,9,7,2,0,1,3,4],[8,9,4,5,3,6,2,0,1,7],
  [9,4,3,8,6,1,7,2,0,5],[2,5,8,1,4,3,6,7,9,0],
];

static immutable string number =
"0123456789012345678901234567890123456789012345678901234567890123456789";

static int charToInt(char chr) {
  return ((chr >= '0') || (chr <= '9')) ? cast(int)(chr - '0') : -1;
}

ubyte checkDigit(string str) {
  ubyte tmpdigit;
  foreach(chr; str) tmpdigit = QG10Matrix[tmpdigit][charToInt(chr)];
  return tmpdigit;
}

void main() {
  auto digit = checkDigit(number);
}

I even tried making checkDigit static, but surprisingly this increased 
average execution time by 1ms.


Anyway, the previopus version (modified to benefit from a little 
optimization too) is almost as performant, even though it includes 
multiplication and sum:


static immutable char[] QG10Matrix =
  "03175986427092154863420687135917509834266123045978" ~
  "36742095815869720134894536201794386172052581436790";

static immutable string number =
"0123456789012345678901234567890123456789012345678901234567890123456789";

static int charToInt(char chr) {
  return ((chr >= '0') || (chr <= '9')) ? cast(int)(chr - '0') : -1;
}

char checkDigit(string str) {
  char tmpdigit = '0';
  foreach(chr; str) tmpdigit =
QG10Matrix[charToInt(chr) + (charToInt(tmpdigit) * 10)];
  return tmpdigit;
}

void main() {
  auto digit = checkDigit(number);
}

I compiled both with -inline -noboundscheck -release and the 
multidimensional array version does perform 1ms faster for a couple 
hundred runs, but I expected the difference to be much more noticeable.


Any idea of what might be happening here?

Did you try it with different backends? llvm (ldc), gcc(gdc)?


Re: Can this implementation of Damm algorithm be optimized?

2017-02-09 Thread Nestor via Digitalmars-d-learn

On Thursday, 9 February 2017 at 21:43:08 UTC, Daniel Kozak wrote:

Any idea of what might be happening here?

Did you try it with different backends? llvm (ldc), gcc(gdc)?


Not really, just standard dmd.

I tried running each algoritm a few times through avgtime using 
different digit lengths (upto 10,000, my PC won't handle much 
more) and different amount of repetitions, and the results aren't 
consistent, some times one algorithm is marginally faster, 
sometimes the other. Apparently the compiler is capable of 
optimizing the unidimensional array version.


Thank you all nevertheless for the suggestions.


Re: Can this implementation of Damm algorithm be optimized?

2017-02-09 Thread Ali Çehreli via Digitalmars-d-learn

On 02/09/2017 02:04 PM, Nestor wrote:

> I tried running each algoritm a few times through avgtime using
> different digit lengths

avgtime profiles the whole process, right? It measures everything that 
is involved in that little program. At least OS starting the program, D 
runtime initializing, program interacting with the console, etc.


Since you're comparing algorithms, you need to take everything else out 
of the equation. A better approach is to use std.datetime.benchmark, 
which would repeat just the algorithm that you're interested in.


Ali



Re: Can this implementation of Damm algorithm be optimized?

2017-02-09 Thread Daniel Kozak via Digitalmars-d-learn

Dne 9.2.2017 v 23:08 Ali Çehreli via Digitalmars-d-learn napsal(a):


On 02/09/2017 02:04 PM, Nestor wrote:

> I tried running each algoritm a few times through avgtime using
> different digit lengths

avgtime profiles the whole process, right? It measures everything that 
is involved in that little program. At least OS starting the program, 
D runtime initializing, program interacting with the console, etc.


Since you're comparing algorithms, you need to take everything else 
out of the equation. A better approach is to use 
std.datetime.benchmark, which would repeat just the algorithm that 
you're interested in.


Ali

Yes this is important, and for example when you used shared libphobos it 
makes really big difference


Re: Can this implementation of Damm algorithm be optimized?

2017-02-09 Thread Era Scarecrow via Digitalmars-d-learn

On Thursday, 9 February 2017 at 19:39:49 UTC, Nestor wrote:
OK I changed the approach using a multidimensional array for 
the matrix so I could ditch arithmetic operations altogether, 
but curiously after measuring a few thousand runs of both 
implementations through avgtime, I see no noticeable 
difference. Why?


 Truthfully, because you'll need tens of millions or hundreds of 
millions in length to determine if it makes a difference and how 
much. Addition, subtraction and simple memory lookups take very 
little time, and since the entire array (100 bytes) fits in the 
cache, it is going to perform very very very well regardless if 
you can optimize it further.


 If you tested this on a much slower system, say an 8bit 6502 the 
differences would be far more pronounced, but not that much 
different.


 Since the algorithm is more or less O(n) optimizing it won't 
make many differences.


 It's possible you could get a speedup by making them ints 
instead of chars, since then it might not have a penalty for the 
'address not divisible by 4' that applies (which is more for ARM 
architectures and less for x86).


 Other optimizations could be to make it multiple levels, taking 
the basic 100 elements and expanding them 2-3 levels deep in a 
lookup and having it do it in more or less a single operation. 
(100 bytes for 1 level, 10,000 for 2 levels, 1,000,000 for 3 
levels, 100,000,000 for 4 levels, etc), but the steps of 
converting it to the array lookup won't give you that much gain, 
although fewer memory lookups but none of them will be cached, so 
any advantage from that is probably lost. Although if you bump up 
the size to 16x10 instead of 10x10, you could use a shift instead 
of *10 which will make that slightly faster (there will be unused 
empty padded spots)


 In theory if you avoid the memory lookup at all, you could gain 
some amount of speed, depending on how it searches a manual 
table, although using a switch-case and a mixin to do all the 
details it feels like it wouldn't give you any gain...


 Division operations are the slowest operations you can do, but 
otherwise most instructions run really fast. Unless you're trying 
to get it smaller (fewer bytes for the call) or shaving for speed 
by instruction cycle counting (like on the 6502) i doubt you'll 
get much benefit.


Re: Strange behaviour of rdmd vs. dmd concerning main function

2017-02-09 Thread Mike Parker via Digitalmars-d-learn

On Thursday, 9 February 2017 at 16:20:29 UTC, berni wrote:
dmd only compiles in the files you actually pass to it. rdmd 
will try to find the required files automatically.


Since you didn't pass the file with the function to dmd, it 
knows it exists, but leaves it out of the final link (it 
assumes it might come from a library or something). That's why 
you see the error.


Ah ok, I understand. So calling with "dmd Special/special.d 
Common/common.d" works.


But when I compile common.d to common.o (with dmd -c common.d) 
and remove common.d after that is there still a possibility to 
link? The obvious doesn't work:


$> dmd Special/special.d Common/common.o Special/special.d(4): 
Error: module common is in file 'common.d' which cannot be read

import path[0] = /usr/include/dmd/phobos
import path[1] = /usr/include/dmd/druntime/import


This is not a linker error. It's a compiler error. You need 
common.d for the import, so the compiler can know which symbols 
are available. For any modules you import, you need either the 
original source file (.d) or a D interface (header) file (.di) 
which contains the type & function declarations and any template 
implementations you need.


Re: Getting familiar with std.process

2017-02-09 Thread jmh530 via Digitalmars-d-learn

On Thursday, 9 February 2017 at 21:36:46 UTC, Ali Çehreli wrote:

On 02/09/2017 12:44 PM, jmh530 wrote:

> I think the issue is that create_file doesn't write to
stdout, it writes
> to file.

Correct. Pipe works by piping the standard input/output streams.

> Other than reading the file and then deleting it, I don't know
> what else to try.

create_file must write to its stdout.

Ali


If only it were that easy. It's not my program writing to file, 
it's some one I didn't write. This was just sort of a beta test. 
I might need to look into the program a bit more.