Re: Maxime's micro allocation benchmark much faster ?

2015-04-01 Thread FG via Digitalmars-d-learn

On 2015-03-31 at 22:56, Laeeth Isharc wrote:

1mm allocations
2.066: 0.844s
2.067: 0.19s


That is great news, thanks!

OT: it's a nasty financier's habit to write 1M and 1MM instead of 1k and 1M.  :P


Re: Maxime's micro allocation benchmark much faster ?

2015-04-01 Thread FG via Digitalmars-d-learn

On 2015-04-01 at 16:52, John Colvin wrote:

On Wednesday, 1 April 2015 at 14:22:57 UTC, Laeeth Isharc wrote:

On Wednesday, 1 April 2015 at 10:35:05 UTC, John Colvin wrote:

On Wednesday, 1 April 2015 at 10:09:12 UTC, FG wrote:

On 2015-03-31 at 22:56, Laeeth Isharc wrote:

1mm allocations
2.066: 0.844s
2.067: 0.19s


That is great news, thanks!

OT: it's a nasty financier's habit to write 1M and 1MM instead of 1k and 1M.  :P


Yeah, what's with that? I've never seen it before.


One cannot entirely escape déformation professionnelle ;) [People mostly write 
1,000 but 1mm although 1m is pedantically correct for 1,000).  Better 
internalize the conventions if one doesn't want to avoid expensive mistakes 
under pressure.


well yes, who doesn't always not want to never avoid mistakes? ;)

Anyway, as I'm sure you know, the rest of the world assumes SI/metric, or 
binary in special cases (damn those JEDEC guys!): 
http://en.wikipedia.org/wiki/Template:Bit_and_byte_prefixes


Yeah, there's that, but at least 1024 and 1000 are still in the same ballpark. 
Bankers are used to the convention and won't mistake M for a million (or you'd 
read it in every newspaper if they did), but it does create havoc when you see 
that convention being used outside of the financial context, or worse, being 
mixed with SI.


Re: The difference in string and char[], readf() and scanf()

2015-03-21 Thread FG via Digitalmars-d-learn

On 2015-03-21 at 16:05, Ivan Kazmenko wrote:

Generate a 10-character string
[...]
Try to copy it with D scanf and printf:
-
import std.stdio;
void main () {
 char [10] a;
 scanf (%s, a.ptr);
 printf (%s\n, a.ptr);
}
-

Only 32767 first characters of the string are actually copied.


In what universe?! Which OS, compiler and architecture?


Re: The difference in string and char[], readf() and scanf()

2015-03-21 Thread FG via Digitalmars-d-learn

On 2015-03-21 at 21:02, Dennis Ritchie wrote:

In what universe?! Which OS, compiler and architecture?

Windows 8.1 x64, dmd 2.066.1:


That's strange. I cannot recreate the problem on Win7 x64 with dmd 2.066.1, 
neither when compiled for 32- nor 64-bit. I have saved the a's to a file and 
use input redirect to load it, while the program is as follows:

import std.stdio;
void main () {
char [10] a;
scanf (%s, a.ptr);
printf (%s\n, a.ptr);
}



  freopen(in.txt, r, din.file);


No, that approach didn't change the result. I still get 1.


Re: The difference in string and char[], readf() and scanf()

2015-03-21 Thread FG via Digitalmars-d-learn

On 2015-03-21 at 22:15, FG wrote:

On 2015-03-21 at 21:02, Dennis Ritchie wrote:

In what universe?! Which OS, compiler and architecture?

Windows 8.1 x64, dmd 2.066.1:


That's strange. I cannot recreate the problem on Win7 x64 with dmd 2.066.1, 
neither when compiled for 32- nor 64-bit. I have saved the a's to a file and 
use input redirect to load it, while the program is as follows:


Oh, wait. I was wrong. I have the same problem. It didn't appear before because 
the file of A's that I used didn't have a \r\n EOL at the end. With those two 
bytes added it failed. It's the EOL at the end of the input word that's the 
problem. I tested four different inputs:

aaa...aaa   OK
aaa...aaa\r\n   FAIL
aaa...aaa bbb   OK
aaa...aaa bbb\r\n   OK


Re: C++ to D

2015-03-11 Thread FG via Digitalmars-d-learn

On 2015-03-11 at 18:27, Dennis Ritchie wrote:

The same without classes in Lisp:
[...]


And your point was...?  I take it, poor c++ is a hint.
Don't compare apples to oranges.


Re: C++ to D

2015-03-11 Thread FG via Digitalmars-d-learn

On 2015-03-11 at 17:42, Dennis Ritchie wrote:

On Wednesday, 11 March 2015 at 16:08:22 UTC, Kagamin wrote:

A hash table? See http://dlang.org/hash-map.html


That is, the input is a string and, depending on what word it contains, is 
called one of the three methods of the class that this line handles. And this 
happens in average constant time (for hash). An associative array where the key 
is a string and value is a function.


Yeah, lookup in D's associative arrays is generally O(1).
Here's the D version of your C++ code. A bit modified, to be more practical,
i.e. you can register hooks yourself and not have them hard-coded into the 
class.



import std.stdio, std.range;

class A
{
alias Hook = void function(ref A, string);
string m_buf;
Hook[string] handlers;
void foo(string s) {
if (auto p = s in handlers)
(*p)(this, s);
m_buf ~= s ~  ;
}
void register(string name, Hook hook) {
handlers[name] = hook;
}
}

void foo1(ref A a, string s) { writeln(s); }
void foo2(ref A a, string s) { writeln(s.retro); }
void foo3(ref A a, string s) { writeln(s, , , a.m_buf); }

void main() {
A a = new A;
a.register(first, foo1);
a.register(second, foo2);
a.register(third, foo3);
a.foo(first);
a.foo(second);
a.foo(third);
}


Re: string-int[] array

2015-03-08 Thread FG via Digitalmars-d-learn

On 2015-03-08 at 20:26, Meta wrote:

On Sunday, 8 March 2015 at 18:57:38 UTC, Kagamin wrote:

http://dpaste.dzfl.pl/2c8d4a7d9ef0 like this.


What in the world is that code doing? I'm having a hard time wrapping my head 
around this.


It's a trick to reuse string internals to store an int.
A string is a struct with two values (length, ptr).
ivalue(i) is used to set ptr = i and length = 0.

Except that with this solution you will confuse empty strings with ints.
You could give such strings special treatment by replacing:

this(string s){ svalue=s; }

with:

this(string s){ svalue=s; if (!s.length) svalue = 
cast(string)(cast(char*)0)[X..X]; }
// where X is some magic int value to mark that we are dealing with an 
empty string,

you'd still be confused if someone actually wanted to store the X value.


Re: how to write a string to a c pointer?

2015-03-06 Thread FG via Digitalmars-d-learn

On 2015-03-06 at 00:25, ketmar wrote:

unicode sux[1].

[1] http://file.bestmx.net/ee/articles/uni_vs_code.pdf



Great article. Thanks, Кетмар

  ⚠ ∑ ♫ ⚽ ☀ ☕ ☺  ≡  ♛


Re: how to write a string to a c pointer?

2015-03-05 Thread FG via Digitalmars-d-learn

On 2015-03-05 at 10:42, Kagamin wrote:

string s;
char[] b = cast(char[])asArray();
b[0..s.length] = s[];


It's a bit more complicated than that if you include cutting string for buffers 
with smaller capacity, doing so respecting UTF-8, and adding a '\0' sentinel, 
since you may want to use the string in C (if I assume correctly). The 
setString function does all that:



import std.stdio, std.range, std.c.stdlib;

class Buffer {
private void *ptr;
private int size;
private int _cap;

public this(int cap) { ptr = malloc(cap); this._cap = cap; }
public ~this() { free(ptr); }
public ubyte[] asArray() { ubyte[] ret = (cast(ubyte*)ptr)[0..cap]; return 
ret; }
public void* getPtr() { return ptr; }
public int cap() { return _cap; }
}

int setString(Buffer buffer, string s)
{
assert(buffer.cap  0);
char[] b = cast(char[])buffer.asArray();
int len = min(s.length, buffer.cap - 1);
int break_at;
// The dchar is essential in walking over UTF-8 code points.
// break_at will hold the last position at which the string can be cleanly 
cut
foreach (int i, dchar v; s) {
if (i == len) { break_at = i; break; }
if (i  len) break;
break_at = i;
}
len = break_at;
b[0..len] = s[0..len];

// add a sentinel if you want to use the string in C
b[len] = '\0';
// you could at this point set buffer.size to len in order to use the 
string in D
return len;
}

void main()
{
string s = ąćęłńóśźż;
foreach (i; 1..24) {
Buffer buffer = new Buffer(i);
int len = setString(buffer, s);
printf(bufsize %2d -- strlen %2d -- %s --\n, i, len, buffer.getPtr);
}
}



Output of the program:

bufsize  1 -- strlen  0 --  --
bufsize  2 -- strlen  0 --  --
bufsize  3 -- strlen  2 -- ą --
bufsize  4 -- strlen  2 -- ą --
bufsize  5 -- strlen  4 -- ąć --
bufsize  6 -- strlen  4 -- ąć --
bufsize  7 -- strlen  6 -- ąćę --
bufsize  8 -- strlen  6 -- ąćę --
bufsize  9 -- strlen  8 -- ąćęł --
bufsize 10 -- strlen  8 -- ąćęł --
bufsize 11 -- strlen 10 -- ąćęłń --
bufsize 12 -- strlen 10 -- ąćęłń --
bufsize 13 -- strlen 12 -- ąćęłńó --
bufsize 14 -- strlen 12 -- ąćęłńó --
bufsize 15 -- strlen 14 -- ąćęłńóś --
bufsize 16 -- strlen 14 -- ąćęłńóś --
bufsize 17 -- strlen 16 -- ąćęłńóśź --
bufsize 18 -- strlen 16 -- ąćęłńóśź --
bufsize 19 -- strlen 16 -- ąćęłńóśź --
bufsize 20 -- strlen 16 -- ąćęłńóśź --
bufsize 21 -- strlen 16 -- ąćęłńóśź --
bufsize 22 -- strlen 16 -- ąćęłńóśź --
bufsize 23 -- strlen 16 -- ąćęłńóśź --




Re: Mimicking C++'s indexing behavior in D associative arrays

2015-02-18 Thread FG via Digitalmars-d-learn

// Assume bar is some associative array of type Foo[string]
Foo* value = key in bar;
if (!value) {
 bar[key] = Foo.init;
 value = bar[key];
}
This seems sub-optimal, given that in involves three hashes (two lookups
and one insertion). Is there a more efficient or cleaner way to do so?


So basically:

Foo v = bar.get(key, Foo.init)
bar[key] = v;

Get is like an ordinary index but it will return the given value if it does not 
exist in the AA.

Of course you probably want to create a new UFCS function to wrap your check + 
default initialize if it doesn't exist.

T grab(T, U)(T[U] aa, U key) if (is(T == struct)) {
 if (key !in aa)
 aa[key] = new T;
 return aa[key];
}


You are searching for the key twice and the original example used pointers.


There is a function called _aaGetX in the runtime that has exactly the required 
behaviour:

// Get pointer to value in associative array indexed by key.
// Add entry for key if it is not already there.
void* _aaGetX(AA* aa, const TypeInfo keyti, in size_t valuesize, in void* 
pkey)

however, using it in normal code could be considered a hack, because it belongs 
to the internal implementation of associative arrays. Anyway, while waiting for 
a better solution to present itself, we might as well have a look at this very 
dirty one. ;)


extern(C) void* _aaGetX(void* aa, const TypeInfo keyti, in size_t 
valuesize, in void* pkey);

V* aaGet(K, V)(V[K] arr, K key) {

return cast(V*)_aaGetX(cast(void*)arr, typeid(K), V.sizeof, 
cast(void*)key);
}

unittest {
int[int] arr = [1: 10, 2: 20, 3: 30];

int *val = arr.aaGet(3); // an existing value

assert(*val == 30);

val = arr.aaGet(4); // aa[4] will be created

assert(*val == int.init);
assert(arr[4] == int.init);
}


Re: @nogc with assoc array

2015-02-16 Thread FG via Digitalmars-d-learn

On 2015-02-16 at 18:58, Benjamin Thaut wrote:

Am 16.02.2015 um 18:55 schrieb Jonathan Marler:

Why is the 'in' operator nogc but the index operator is not?

void main() @nogc
{
 int[int] a;
 auto v = 0 in a; // OK
 auto w = a[0];   // Error: indexing an associative
  // array in @nogc function main may
  // cause GC allocation
}


Because the index operator throws a OutOfRange exception and throwing 
exceptions allocates, maybe?


Range violation is an Error, but never mind that. The real question is: given 
all the work related to @nogc, wouldn't it be better for such common Errors to 
be preallocated and only have file and line updated when they are thrown?

@nogc already, because they simply cast typeid(OutOfMemoryError).init or 
typeid(InvalidMemoryOperationError).init:
extern (C) void onOutOfMemoryError(void* pretend_sideffect = null) @trusted 
pure nothrow @nogc
extern (C) void onInvalidMemoryOperationError(void* pretend_sideffect = null) 
@trusted pure nothrow @nogc

Could be made @nogc with one object of each kind preallocated:
extern (C) void onAssertError( string file = __FILE__, size_t line = __LINE__ ) 
nothrow
extern (C) void onRangeError( string file = __FILE__, size_t line = __LINE__ ) 
@safe pure nothrow
extern (C) void onSwitchError( string file = __FILE__, size_t line = __LINE__ ) 
@safe pure nothrow



Re: @nogc with assoc array

2015-02-16 Thread FG via Digitalmars-d-learn

On 2015-02-16 at 22:12, Jonathan Marler wrote:

On Monday, 16 February 2015 at 19:12:45 UTC, FG wrote:

Range violation is an Error, but never mind that. The real question is: given 
all the work related to @nogc, wouldn't it be better for such common Errors to 
be preallocated and only have file and line updated when they are thrown?

@nogc already, because they simply cast typeid(OutOfMemoryError).init or 
typeid(InvalidMemoryOperationError).init:
extern (C) void onOutOfMemoryError(void* pretend_sideffect = null) @trusted 
pure nothrow @nogc
extern (C) void onInvalidMemoryOperationError(void* pretend_sideffect = null) 
@trusted pure nothrow @nogc

Could be made @nogc with one object of each kind preallocated:
extern (C) void onAssertError( string file = __FILE__, size_t line = __LINE__ ) 
nothrow
extern (C) void onRangeError( string file = __FILE__, size_t line = __LINE__ ) 
@safe pure nothrow
extern (C) void onSwitchError( string file = __FILE__, size_t line = __LINE__ ) 
@safe pure nothrow


This could be a good idea for some types of exceptions.  I believe OutOfMemory 
is already pre-allocated (it has to be since you can't allocate it once you are 
out of memory).  The problem with your suggestion is that if you allow the 
exception to be updated with the line number/filename(it isn't immutable), then 
you have to store it in TLS memory.  That may be an acceptable tradeoff, but 
you have to take that into consideration.  Also if you have a chain of 
exceptions you wouldn't be able to include the same exception more then once in 
the chain.

The problem D has with exceptions and GC memory is complex and will have 
different optimal solutions in different cases.  In some cases, it would be 
better for D to support non-GC heap allocated exceptions.  Maybe these types of 
exceptions could be derived from another class so the user code will know that 
the memory needs to be freed.  There are also other ideas but my point is we 
should make a plan about what solutions we think would be good to implement and 
determine which ones we want to tackle first.


Yes, they would be in TLS. I know exceptions in general are a complex problem, 
therefore I limited the comment only to errors, because forbidding the use of 
`aa[key]` in @nogc seemed odd (although I do think that `aa.get(key, default)` 
and `key in aa` are superior to `aa[key]`). I have seen a few examples of 
Exception chaining, but not Error chaining, and since Error trumps Exception, 
whatever else was raised was of less importance to me, so I didn't give much 
thought to that.

And as for the extra non-GC exception class, maybe, I'm not sure, but it should 
nevertheless be a subclass of Exception to allow for a simple catch-all.


Re: @nogc with assoc array

2015-02-16 Thread FG via Digitalmars-d-learn

On 2015-02-17 at 03:35, Jonathan Marler wrote:

On Tuesday, 17 February 2015 at 00:00:54 UTC, FG wrote:

Yes, they would be in TLS. I know exceptions in general are a complex problem, 
therefore I limited the comment only to errors, because forbidding the use of 
`aa[key]` in @nogc seemed odd (although I do think that `aa.get(key, default)` 
and `key in aa` are superior to `aa[key]`). I have seen a few examples of 
Exception chaining, but not Error chaining, and since Error trumps Exception, 
whatever else was raised was of less importance to me, so I didn't give much 
thought to that.


I'm not sure what you mean by Errors?  Are you talking about asserts?


Asserts among them. I was talking about the two classes of Throwable: Error and 
Exception.

Errors: AssertError, FinalizeError, HiddenFuncError, 
InvalidMemoryOperationError, InvalidPointerError, NotImplementedError, 
OutOfMemoryError, ParallelForeachError, RangeError, SwitchError, SysError, 
ThreadError.

Exceptions: Base64Exception, CSVException, ConvException, CurlException, 
EncodingException, ErrnoException, FiberException,
FileException, FormatException, GetOptException, JSONException, 
OverflowException, ...


Re: ranges reading garbage

2015-02-15 Thread FG via Digitalmars-d-learn

On 2015-02-15 at 19:43, bearophile wrote:

void foo(in float[] data, in float[] xs, in float[] ys) @safe {
 iota(0, data.length, ys.length)
 .map!(xBase = iota(xBase, xBase + ys.length - 1)
.map!(y = [y, y+ys.length, y+ys.length+1, y+1])
.joiner)
 .joiner
 .writeln;
}

void main() {
 foo([1,2,3,4,5,6,7,8], [0.1,0.2], [10,20,30,40]);
}


Odd... Still something is wrong. It prints:
[0, 4, 5, 1, 1, 5, 6, 2, 2, 6, 7, 3, 4, 8, 9, 5, 5, 5, 6, 6, 6, 6, 7, 7]

instead of this:
[0, 4, 5, 1, 1, 5, 6, 2, 2, 6, 7, 3, 4, 8, 9, 5, 5, 9, 10, 6, 6, 10, 11, 7]


Re: To write such an expressive code D

2015-02-10 Thread FG via Digitalmars-d-learn

On 2015-02-11 at 01:56, bearophile wrote:

Alternative solution closer to the F# code:

import std.stdio, std.algorithm, std.typecons;

int f(T)(T t) if (isTuple!T) {
 return t.predSwitch(
 tuple(0, 0, 0), 0,
 tuple(0, 1, 1), 0,
 tuple(1, 0, 1), 0,
 tuple(1, 1, 0), 0,
 /*else*/ 1);
}

void main() {
 foreach (immutable a; 0 .. 2)
 foreach (immutable b; 0 .. 2)
 foreach (immutable c; 0 .. 2)
 writefln(%d xor %d xor %d = %d, a, b, c, tuple(a, b, c).f);
}


Why bend over and try to make it F#? Screw the F# guy.
He was cheating with a switch, so why can't we cheat?

foreach(i;0..8)writefln(%d xor %d xor %d = 
%s,!!(i4),!!(i2),!!(i1),01101001[i]);

Assimilate this!

Oh wait, you needed a function. OK, here's a function
(and just replace 01101001[i] with xxor(i4,i2,i1)):

int xxor(int a, int b, int c) {return 
(abc)||(!a!bc)||(!ab!c)||(a!b!c);}

If it makes him dislike D even more, great! Mission accomplished. :)


Re: parse string as char

2015-02-09 Thread FG via Digitalmars-d-learn

Of course consuming it dchar by dchar also works:

string s = `\tabŁŃ\r\nx`;
assert(parseDchar(s) == '\t');
assert(parseDchar(s) == 'a');
assert(parseDchar(s) == 'b');
assert(parseDchar(s) == 'Ł');
assert(parseDchar(s) == 'Ń');
assert(parseDchar(s) == '\r');
assert(parseDchar(s) == '\n');
assert(parseDchar(s) == 'x');
assert(s.empty);


Re: parse string as char

2015-02-09 Thread FG via Digitalmars-d-learn

On 2015-02-09 at 03:40, Timothee Cour via Digitalmars-d-learn wrote:

Is there a simple way to parse a string as a char?
eg:
unittest{
   assert(parseChar(`a`)=='a');
   assert(parseChar(`\n`)=='\n'); //NOTE: I'm looking at `\n` not \n
   // should also work with other forms of characters, see 
http://dlang.org/lex.html
}
Note, std.conv.to http://std.conv.to doesn't work (`\n`.to!char does not work)



parseEscape does something similar to what you need:
https://github.com/D-Programming-Language/phobos/blob/master/std/conv.d#L3415

Unfortunately it is private and handles only escapes, so here is a modified 
version:



import std.range, std.stdio;

dchar parseDchar(Source)(ref Source s)
if (isInputRange!Source  isSomeChar!(ElementType!Source))
{
import std.utf, std.conv;
if (s.front != '\\') {
dchar c = decodeFront(s);
return c;
}
s.popFront;
if (s.empty)
throw new Exception(Unterminated escape sequence);

dchar getHexDigit()(ref Source s_ = s)  // workaround
{
import std.ascii : isAlpha, isHexDigit;
if (s_.empty)
throw new Exception(Unterminated escape sequence);
s_.popFront();
if (s_.empty)
throw new Exception(Unterminated escape sequence);
dchar c = s_.front;
if (!isHexDigit(c))
throw new Exception(Hex digit is missing);
return isAlpha(c) ? ((c  ~0x20) - ('A' - 10)) : c - '0';
}

dchar result;

switch (s.front)
{
case '':   result = '\';  break;
case '\'':  result = '\'';  break;
case '0':   result = '\0';  break;
case '?':   result = '\?';  break;
case '\\':  result = '\\';  break;
case 'a':   result = '\a';  break;
case 'b':   result = '\b';  break;
case 'f':   result = '\f';  break;
case 'n':   result = '\n';  break;
case 'r':   result = '\r';  break;
case 't':   result = '\t';  break;
case 'v':   result = '\v';  break;
case 'x':
result  = getHexDigit()  4;
result |= getHexDigit();
break;
case 'u':
result  = getHexDigit()  12;
result |= getHexDigit()  8;
result |= getHexDigit()  4;
result |= getHexDigit();
break;
case 'U':
result  = getHexDigit()  28;
result |= getHexDigit()  24;
result |= getHexDigit()  20;
result |= getHexDigit()  16;
result |= getHexDigit()  12;
result |= getHexDigit()  8;
result |= getHexDigit()  4;
result |= getHexDigit();
break;
default:
throw new Exception(Unknown escape character  ~ 
to!string(s.front));
}
if (s.empty)
throw new Exception(Unterminated escape sequence);

s.popFront();

return result;
}

dstring parseString(Source)(Source s)
if (isInputRange!Source  isSomeChar!(ElementType!Source))
{
import std.array;
dchar[] result;
auto app = appender(result);
while (!s.empty)
app.put(parseDchar(s));
return app.data;
}

unittest
{
assert(parseString(``) == d);
assert(parseString(`abc`) == abcd);
assert(parseString(`abc\\n\\n\\n`) == abc\\n\\n\\nd);
assert(parseString(`ąćę\\nłńó`) == ąćę\\nłńód);
assert(parseString(`abc\\\nx`) == abc\\\nxd);
assert(parseString(`\tabc\r\nx`) == \tabc\r\nxd);
assert(parseString(` \x20 `) ==d);
}






Re: How to write similar code D?

2015-02-09 Thread FG via Digitalmars-d-learn

On 2015-02-10 at 01:41, bearophile wrote:


 auto query = iota(2, 12)
  .map!(c = Tuple!(int,length, int,height, 
int,hypotenuse)
   (2 * c, c ^^ 2 - 1, c ^^ 2 + 1))
  .map!(x = %3d%4d%4d.format(x.height, x.hypotenuse, 
x.length));



I took advantage of the fact that all elements were of the same type:

auto query = iota(2, 2 + 10)
.map!(c = [Length: 2 * c, Height: c * c - 1, Hypotenuse: c * c + 1])
.map!(x = format(%4d%4d%4d, x[Height], x[Hypotenuse], x[Length]));
...

and was surprised that it worked straight away. :)
But definitely this looks better and less complicated:

auto query = iota(2, 12)
.map!(c = tuple(c ^^ 2 - 1, c ^^ 2 + 1, 2 * c));
foreach (x; query)
writefln(%4d%4d%4d, x[]);

It's the foreach version, since `each` isn't officially out yet.


Re: strange work of GC

2015-02-08 Thread FG via Digitalmars-d-learn

On 2015-02-08 at 06:36, Mike Parker wrote:

On 2/8/2015 11:32 AM, FG wrote:

On 2015-02-08 at 01:20, Mike Parker wrote:

In your case, forget destructors and the destroy method. Just
implement a common method on all of your objects that need cleanup
(perhaps name it 'terminate') and call that. This gives you the
deterministic destruction that you want (the same as calling destroy
on each object) while avoiding the possibility that the GC can call
your cleanup method.


What is wrong with doing all that in a destructor? I don't know if it is
just an implementation detail, but a destroyed object is either
zero-filled or reinitialized to the default, so, if implemented
correctly, it knows whether a cleanup is required (and I'm assuming that
a model of simple single ownership is used, like in Qt). Therefore it
should be safe to use destroy to finalize an object and even to put
destroy in its destructor in order to perform a controlled cascade
destruction of all the children that require immediate cleanup (ie.
releasing expensive non-GC resources, closing connections, etc.). The
main difference with C++ being that you would only force finalization,
but then let the GC free the memory in its normal fashion.




First, there are no guarantees about when or if a destructor is going to be 
called. The fact that the current GC calls the destructors of all live objects 
at application shutdown is an implementation detail. If you want deterministic 
destruction, you can not rely on destructors.


I admit that I became accustomed to that implementation detail and would like 
it to stay.


Second, if you are going to call destroy on every object to clean them up, then 
in principle that's fine. But now you have to be careful that no mistakes slip 
into the code base, e.g. forgetting to call destroy on an object that touches 
GC memory in its destructor.


One could also forget to call terminate(). :)

The advantage of ~this() is that it is standard, while terminate() is not. You 
call it that, someone else might call it finalize(), close() or whatever. I do 
see a benefit in using terminate() directly instead of the GC-fired destructor, 
because it's not constrained by having to steer clear of the 
InvalidMemoryOperationError, but it is overshadowed by inconvenience. So let's 
assume that terminate() is GC-friendly (ie. would work even when called from a 
destructor).


By separating resource cleanup from object destruction, you get both 
deterministic cleanup and more freedom in choosing whether or not to clean up 
at all.


I separate them only when the object needs it (flush a write, close a 
connection, release a big chunk of memory, etc.), by calling destroy and not 
waiting until the GC decides that it's time to deallocate memory for that 
object and performs the destruction by itself. For every other case of object I 
also do not care when and if it gets cleaned up.


At app exit, I only call terminate on objects that absolutely need to do 
something before the process exits, like writing a final message to a log file 
[...] resource cleanup only happens when and if I say.


Exactly, but if I put a call to terminate() in the destructor, then clean up 
will be automated in those cases when I don't care about cleaning up myself or 
*forget* to do it.


That just isn't possible if all cleanup is in destructors. You either have to 
destroy *every* object yourself, or be vigilant about which objects you let the 
GC call destructors on.


Why not? Are you saying that because of the lack of guarantees that a 
destructor will be called by the GC? And not *every* object -- it was stated 
that we don't care about all those objects that don't require special clean up.



Re: why GC not work?

2015-02-08 Thread FG via Digitalmars-d-learn

On 2015-02-08 at 15:56, mzf wrote:

On Saturday, 7 February 2015 at 06:08:39 UTC, ketmar wrote:

On Sat, 07 Feb 2015 04:30:07 +, Safety0ff wrote:


False pointers, current GC is not precise.


not only that. constantly allocating big chunks of memory will inevitably
lead to OOM due to current GC design. you can check it with manual
freeing. there were some topics about it, and the solution is either use
64 bit OS ('cause the memory is here, but there is no address space to
allocate it), or use `malloc()` and `free()` from libc.


hi,i still have two questions:

1. how large is the big chunks  ? 10MB? 50MB? ...
   where are topics about this?
   if I don't know the exact size, it is very likely a memory leak


You wrote yourself, that you used win7 x86,dmd v2.066.0, that is x86 and not 
x86-64.
In 32-bits even with blocks as small as 1 MB there is a chance that the garbage 
collector will think some data on stack is a pointer to that block because when 
cast to void* it could point right into that allocated block of memory.
 

2. auto buf = new byte[](1024*1024*100);
   now the gc can't free this buf.
   can i free it by manual?


Yes. import core.memory; GC.free(buf.ptr); // and don't use buf afterwards


Re: why GC not work?

2015-02-08 Thread FG via Digitalmars-d-learn

On 2015-02-08 at 19:15, safety0ff wrote:

On Sunday, 8 February 2015 at 16:23:44 UTC, FG wrote:



2. auto buf = new byte[](1024*1024*100);
  now the gc can't free this buf.
  can i free it by manual?


Yes. import core.memory; GC.free(buf.ptr); // and don't use buf afterwards


That won't work, see:
http://forum.dlang.org/thread/uankmwjejsitmlmrb...@forum.dlang.org



Perhaps it was fixed in DMD 2.066.1, because this works for me just fine:

import core.memory;

void testGC()
{
auto b = new byte[](1024 * 1024 * 100);
GC.free(b.ptr);
}

void main()
{
foreach (i; 1..100)
testGC();
}


Re: strange work of GC

2015-02-07 Thread FG via Digitalmars-d-learn

On 2015-02-07 at 12:02, Andrey Derzhavin wrote:

If a destroy method is used together with GC inside of my app,it makes my app 
unstable.
In this case I need to choose how to destroy my objects: 1) always manually by method 
destroy, but without GC; 2) or always automatically by GC, but without using the 
destroy method.
In the first case I need to know how can I disable the automatic GC in my app?
In the second case - how can I disable the destroy method calls inside of my 
app?


Why do you want to use destroy? Put GC.collect() after the call to fn1 and GC 
cleanup will work just fine[1], I've checked. Are you talking about a different 
program now?

[1] Assuming that you compile the program as 64-bit and not 32-bit.


Re: Using reduce with user types

2015-02-07 Thread FG via Digitalmars-d-learn

On 2015-02-07 at 13:47, Kadir Erdem Demir wrote:


 auto sum = aArr.reduce!((a,b) = a.count + b.count);

The line above gives

C:\D\dmd2\windows\bin\..\..\src\phobos\std\algorithm.d(770): Error: cannot 
implicitly convert expression (__lambda3(result, front(_param_1))) of type int 
to A
C:\D\dmd2\windows\bin\..\..\src\phobos\std\algorithm.d(791): Error: template 
instance app.main.reduce!((a, b) = a.count + b.count).reduce!(A, A[]) error 
instantiating
source\app.d(363):instantiated from here: reduce!(A[])



// auto sum = aArr.reduce!((a,b) = a.count + b.count); // Wrong

auto sum = reduce!((a, b) = a + b.count)(0, aArr); // Good


See here: http://dlang.org/phobos/std_algorithm.html#.reduce


Re: strange work of GC

2015-02-07 Thread FG via Digitalmars-d-learn

On 2015-02-08 at 01:20, Mike Parker wrote:

In your case, forget destructors and the destroy method. Just implement a 
common method on all of your objects that need cleanup (perhaps name it 
'terminate') and call that. This gives you the deterministic destruction that 
you want (the same as calling destroy on each object) while avoiding the 
possibility that the GC can call your cleanup method.


What is wrong with doing all that in a destructor? I don't know if it is just 
an implementation detail, but a destroyed object is either zero-filled or 
reinitialized to the default, so, if implemented correctly, it knows whether a 
cleanup is required (and I'm assuming that a model of simple single ownership 
is used, like in Qt). Therefore it should be safe to use destroy to finalize an 
object and even to put destroy in its destructor in order to perform a 
controlled cascade destruction of all the children that require immediate 
cleanup (ie. releasing expensive non-GC resources, closing connections, etc.). 
The main difference with C++ being that you would only force finalization, but 
then let the GC free the memory in its normal fashion.





Re: Trying to make a TCP server, client connects and disconnects immediately

2015-02-06 Thread FG via Digitalmars-d-learn

On 2015-02-06 at 05:17, Gan wrote:

Oh sweet. Though if one message length is off by even 1 byte, then all future 
messages get corrupted?


Yes, but you can easily detect that by adding a magic number and packet 
checksum to the header.


Re: Issue with template function

2015-02-06 Thread FG via Digitalmars-d-learn

On 2015-02-06 at 18:09, Charles wrote:

 readString(toBytes!char(['t','e','s','t']),0,4).writeln;
 readString(toBytes!string(test),0,4).writeln;// This is line 39


That second line makes no sense (you didn't provide an array of strings).
Why toBytes!string(test) and not toBytes!char(test) or rather:
toBytes!(immutable char)(test) ?


Re: how can I get a reference of array?

2015-02-05 Thread FG via Digitalmars-d-learn

On 2015-02-05 at 09:58, bearophile wrote:

zhmt:


Will arr.ptr change in the future?

As the array add more members , it need more memroy, then remalloc may be 
called, the pointer maybe change, then the stored pointer will be invalid.

Will this happen?


Yes, it can happen.


Therefore, don't use arr.ptr directly, but always access it via arr or a.arr.

class A { public int[] * arr; }
int[] arr;
A a = new A;
a.arr = arr;
... // lots of adding to arr
... // and yet still, a.arr == arr

Even when the array in the memory gets reallocated by adding to arr, causing 
arr.length and arr.ptr to be updated, the arr struct itself will remain in the 
same spot, so pointers to it, including a.arr, are valid. (Unless arr goes out 
of scope before a, in which case you would be in deep trouble.)


Re: Do you have a better way to remove element from a array?

2015-02-05 Thread FG via Digitalmars-d-learn

On 2015-02-05 at 17:25, bearophile wrote:

It has to be a void function (or perhaps bettter it can return true/false if it 
has removed the item, so it becomes @nogc and nothrow).
And it has to remove the first item equal to the given one.
You can then add a second function that removes at a given index (like 
removeAt).


I was never a fan of STL's erase-remove idiom, although the decoupling of 
algorithms and containers is in general a great idea. However, in D algorithms 
can be smarter, because they operate on ranges instead of iterators. I don't 
see why remove has to follow the C++ example. Therefore I have to ask:

Is there any reason why `remove` doesn't take the range by reference and 
`popBack` as many elements as were removed?


Re: Want to read a whole file as utf-8

2015-02-03 Thread FG via Digitalmars-d-learn

On 2015-02-03 at 19:53, Foo wrote:

How can I do that without any GC allocation? Nothing in std.file seems to be 
marked with @nogc

I'm asking since it seems very complicated to do that with C++, maybe D is a 
better choice, then we would probably move our whole project from C++ to D.


Looks like std.stdio isn't marked with @nogc all the way either.

So for now the temporary solution would be to use std.c.stdio.
Get the file size, malloc a buffer large enough for it[1],
use std.c.stdio.read to fill it, assign it to a char[] slice
and std.utf.decode to consume the text...

Oh wait, decode isn't @nogc either. FFS, what now?


[1] I assume the file is small, otherwise there would be an extra step
involved where after nearing the end of the buffer you move the rest
of the data to the front, read new data after it, and continue decoding.


Re: Want to read a whole file as utf-8

2015-02-03 Thread FG via Digitalmars-d-learn

On 2015-02-03 at 20:50, Tobias Pankrath wrote:

Use std.utf.validate instead of decode. It will only allocate one exception if 
necessary.


Looks to me like it uses decode internally...

But Foo, do you have to use @nogc? It still looks like it's work in progress,
and lack of it doesn't mean that the GC is actually involved in the function.
It will probably take several months for the obvious nogc parts of the std lib
to get annotated, and much longer to get rid of unnecessary use of the GC.
So maybe the solution for now is to verify the source code of the function in
question with ones own set of eyeballs and decide if it's good enough for use,
ie. doesn't leak too much?


Re: Want to read a whole file as utf-8

2015-02-03 Thread FG via Digitalmars-d-learn

On 2015-02-04 at 00:07, Foo wrote:

How would I use decoding for that? Isn't there a way to read the file as utf8 
or event better, as unicode?


Well, apparently the utf-8-aware foreach loop still works just fine.
This program shows the file size and the number of unicode glyps, or whatever 
they are called:

import core.stdc.stdio;
int main() @nogc
{
const int bufSize = 64000;
char[bufSize] buffer;
size_t bytesRead, count;
FILE* f = core.stdc.stdio.fopen(test.d, r);
if (!f)
return 1;
bytesRead = fread(cast(void*)buffer, 1, bufSize, f);
if (bytesRead  bufSize - 1) {
printf(File is too big);
return 1;
}
if (!bytesRead)
return 2;
foreach (dchar d; buffer[0..bytesRead])
count++;
printf(read %d bytes, %d unicode characters\n, bytesRead, count);
fclose(f);
return 0;
}

Outputs for example this: read 838 bytes, 829 unicode characters

(It would be more complicated if it had to process bigger files.)


Re: Want to read a whole file as utf-8

2015-02-03 Thread FG via Digitalmars-d-learn

On 2015-02-04 at 01:56, Namespace wrote:


 FILE* f = fopen(filename.ptr, rb);
 fseek(f, 0, SEEK_END);
 immutable size_t fsize = ftell(f);
 fseek(f, 0, SEEK_SET);



That's quite a smart way to get the size of the file.

I started with std.file.getSize (which obviously isn't marked as @nogc) and 
ended up with the monstrosity below (which I have only compiled on Windows), so 
I decided not to mention it in my previous post. Wouldn't be the point anyway, 
since I have only shown an example with a single-fill fixed buffer. But here it 
is, rendered useless by your code:

long getFileSize(const char* cName) @nogc
{
version(Windows)
{
import core.sys.windows.windows;
WIN32_FILE_ATTRIBUTE_DATA fad;
if (!GetFileAttributesExA(cName, 
GET_FILEEX_INFO_LEVELS.GetFileExInfoStandard, fad))
return -1;
ULARGE_INTEGER li;
li.LowPart = fad.nFileSizeLow;
li.HighPart = fad.nFileSizeHigh;
return li.QuadPart;
}
else version(Posix)
{
import core.sys.posix.sys.stat;
stat_t statbuf = void;
if (stat(cName, statbuf))
return -1;
return statbuf.st_size;
}
}


Re: Conway's game of life

2015-02-02 Thread FG via Digitalmars-d-learn

On 2015-02-02 at 12:23, FG wrote:

Cell(0,3) is not a neighbour bit fits the (diff1 == 1 || diff2 == 1) criterion.


s/bit/but/


Re: Conway's game of life

2015-02-02 Thread FG via Digitalmars-d-learn

Bloody Thunderbird has sent a reply to the OP and not to the NG.

On 2015-02-02 at 11:45, gedaiu wrote:

I don't think that the line of code is wrong. If use  the function will check 
for neighbours only on diagonals. Having || allows the search on the vertical and 
horizontal axis and diagonals.


In short: Yes,  alone would check only diagonals, but I forgot to tell you to 
also change the ==.

(diff1 == 1 || diff2 == 1) -- bad, accepts whole neighbouring rows and columns
(diff1 == 1  diff2 == 1) -- bad, accepts only neighbouring diagonals
(diff1 = 1  diff2 = 1) -- correct, I think :)

This unittest should show the difference:

unittest {
CellList world = [ Cell(0,0), Cell(0,1), Cell(0,2), Cell(0,3) ];
assertEqual(Cell(1,1).neighbours(world), 3);
}

Cell(0,3) is not a neighbour bit fits the (diff1 == 1 || diff2 == 1) criterion.


Re: cast a C char array - offset ?

2015-02-02 Thread FG via Digitalmars-d-learn

On 2015-02-02 at 13:16, irtcupc wrote:

The manual section about interfacing from c states that type[] is 
inter-compatible from C to D,

however, I face this strange case:

- C declaration:
char identifier[64];

- D declaration:
char[64] identifier;

- the result is only correct if i slice by (- pointer size):
char[64] fromC(char[64] * thing)
{
 const offs = size_t.sizeof;
 return thing[-offs.sizeof .. $-offs];
}

Is this correct ?



So you have to shift the whole array right by 4 or 8 bytes? Strange.
Looks like an alignment issue. Is identifier part of a bigger structure?


Re: cast a C char array - offset ?

2015-02-02 Thread FG via Digitalmars-d-learn

On 2015-02-02 at 14:40, irtcupc wrote:

On Monday, 2 February 2015 at 13:34:28 UTC, ketmar wrote:

  struct _Disasm {
  align(1):

the difference is that `align` before struct tells how structure should
be packed (i.e. when you have `_Disasm[2] arr`). and `align` *inside*
struct tells compiler how struct *members* should be packed.


Thx, problem fixed, it works now.


Yeah, without the align(1) inside the struct, the members of the struct were 
not crammed, so VirtualAddr started in byte x+8 instead of x+4 (on a 32-bit 
machine), and that was the source of the extra 4-byte shift you encountered.


Re: Can't understand how to compare DateTime with opCmp

2015-02-01 Thread FG via Digitalmars-d-learn

On 2015-02-01 at 16:04, Suliman wrote:

opCmp(in DateTime rhs);

what is rhs?


RHS is probably short of right hand side, ie. the argument on the right side of 
the operator in a binary operator expression. In `a  b` it would be b.


I am trying to do something like this:
if( DateTime.opCmp(dtindb, outoftime));

But it's seems that I wrong understand how to use this function...


No. That would be `if (dtindb.opCmp(outoftime))`, but it's simpler to write `if 
(dtindb  outoftime)`




Re: Conway's game of life

2015-02-01 Thread FG via Digitalmars-d-learn

On 2015-02-01 at 22:00, gedaiu wrote:

I implemented Conway's game of life in D.


I think you are playing a different game here.

/// Count cell neighbours
long neighbours(Cell myCell, CellList list) {
long cnt;
foreach(cell; list) {
auto diff1 = abs(myCell.x - cell.x);
auto diff2 = abs(myCell.y - cell.y);
if(diff1 == 1 || diff2 == 1) cnt++;   // Why || instead of  ???
}
return cnt;
}


Re: std.algorithm sort() and reverse() confusion

2015-01-30 Thread FG via Digitalmars-d-learn

On 2015-01-30 at 17:07, Paul wrote:

writeln(Sorted, reversed: , reverse(myVals));

Gives me...

Error: template std.stdio.writeln cannot deduce function from argument types 
!()(string, void)


As it should, because reverse returns nothing, void.
But you may wonder what the design choice behind that was that reverse doesn't 
return the range itself while sort does (a SortedRange, specifically).


Re: std.algorithm sort() and reverse() confusion

2015-01-30 Thread FG via Digitalmars-d-learn

On 2015-01-30 at 18:42, FG wrote:

But you may wonder what the design choice behind that was that reverse doesn't 
return the range itself while sort does (a SortedRange, specifically).


Although, after thinking about it, it makes sense. sort is used mostly to 
enforce that something is sorted in case it isn't already, so chaining it with 
other functions is reasonable, while in case of reverse you don't normally call 
it very often, it's cheaper to wrap the range in a retro range and iterate 
backwards when required, without touching the original.



Re: Thread.sleep( dur!(msecs)( 50 ) ); // sleep for 50 milliseconds

2015-01-30 Thread FG via Digitalmars-d-learn

On 2015-01-30 at 12:08, Vladimir Panteleev wrote:

On Friday, 30 January 2015 at 11:04:47 UTC, FG wrote:

Bug or correct behaviour?


Bug: https://issues.dlang.org/show_bug.cgi?id=1238


https://github.com/D-Programming-Language/dmd/pull/3743

The fix is pretty much a one-liner.
Probably 2.067 will already include it, right?


Re: Thread.sleep( dur!(msecs)( 50 ) ); // sleep for 50 milliseconds

2015-01-30 Thread FG via Digitalmars-d-learn

Error: module app struct std.regex.Thread(DataIndex) is private


Did you import core.thread?


Re: Thread.sleep( dur!(msecs)( 50 ) ); // sleep for 50 milliseconds

2015-01-30 Thread FG via Digitalmars-d-learn

On 2015-01-30 at 11:55, FG wrote:

Error: module app struct std.regex.Thread(DataIndex) is private


Did you import core.thread?


This is silly. Thread is internal to std.regex, yet when importing both 
std.regex and core.thread, you still get an error:

src.d(10): Error: core.thread.Thread at ..\thread.d(514) conflicts with 
std.regex.Thread(Dat
aIndex) at ..\src\phobos\std\regex.d(4588)

The way around is of course the use of a fully qualified name:

core.thread.Thread.sleep( dur!(msecs)( 50 ) );

but there really should be no need for this, since std.regex.Thread is private. 
Bug or correct behaviour?


Re: What is @return?

2015-01-29 Thread FG via Digitalmars-d-learn


@property auto info() @safe @nothrow @pure @return const { return this; }

It is mesmerizing...   (@ _ @)


Re: I left my program open for 9 hours and it used up 700mb of ram, could someone review it?

2015-01-27 Thread FG via Digitalmars-d-learn

On 2015-01-27 at 23:39, Gan wrote:

I commented out some stuff and it appears my massive memory consumption comes 
from my tile.redraw function:
...
Would you know why this is using hundreds of mb of rams?


Looks OK, so probably it is not the cause by itself.
I would add a piece of code to SpaceBackground.draw that for every few calls to 
this function would print out tiles.length and stack.length to the console. 
Just to make sure that those arrays don't grow out of control, before accusing 
anything else.


Re: I left my program open for 9 hours and it used up 700mb of ram, could someone review it?

2015-01-27 Thread FG via Digitalmars-d-learn

On 2015-01-28 at 03:04, Vladimir Panteleev wrote:

What type is CircleShape?
If it is a class, or otherwise contains pointers, then this is probably the 
source of your problem.


class CircleShape : Shape is defined in dsfml.graphics.circleshape, so there's 
no going around this...


- Building your program for x86_64 - 64 bits of address space will make fake 
pointer pinning very unlikely


The binary included in the zip was 64-bit, so fake pointers shouldn't be that 
much of a problem.

Oh, and I take back what I said about suspecting that SpaceBackground.stack 
grows infinitely. It probably doesn't. I don't have DSFML installed, and 
therefore couldn't recreate the behaviour.


Re: crash on args.getopt

2015-01-25 Thread FG via Digitalmars-d-learn

On 2015-01-25 at 11:42, Tobias Pankrath wrote:

On Sunday, 25 January 2015 at 10:21:34 UTC, Suliman wrote:

But is it good practice to fail with exception during passing unknown 
parameters? Maybe std.getopt.config.passThrough should be as default?

I really can't remember Apps that crush if pass to in unknown parameters.


Almost all programs fail with an error message, if you pass unknown parameter. 
Just catch that exception.


It's much better to fail up front than to create the illusion that everything is fine after the user has 
mistyped one of the parameters. Let's say foo a b copies from a to b, but foo --reverse a 
b does the opposite. Then, when someone types for example foo --revrse a b, and it is 
silently accepted, the program does exactly the opposite of what the user expects!

A side note: GTK applications accept extra parameters used to initialize GTK, but it is 
not passThrough. What really happens is that the app calls gtk_init(argc, 
argv) (or Main.init(args) in case of GtkD) before it starts parsing arguments on 
its own. The call to gtk_init removes the options recognized by GTK from the list of 
program arguments, and this filtered array can be then processed in a normal way -- 
which means that whichever parameters are still left unrecognised, the program should 
fail with an error message.


Re: endsWith - for a string vs an array of strings

2015-01-10 Thread FG via Digitalmars-d-learn

On 2015-01-10 at 21:58, bearophile wrote:

Needles is not an array type, it's a type tuple, so withOneOfThese doesn't 
accept an array of strings. [...]
So if you really want to pack the strings in some kind of unity, you can do 
this as workaround: [...]


I would suggest create a function that does the same thing as endsWith(Range, 
Needles...) but instead of Needles expanded as a list of arguments it takes in 
a range of them. In fact I was surprised that there was no such function in 
std.algorithm present. Therefore I have written endsWithAny for this purpose a 
moment ago. Is it any good? Please correct if necessary.




import std.array;
import std.string;
import std.stdio;
import std.range;

uint endsWithAny(alias pred = a == b, Range, Needles)(Range haystack, Needles 
needles)
if (isBidirectionalRange!Range  isInputRange!Needles 
is(typeof(.endsWith!pred(haystack, needles.front)) : bool))
{
foreach (i, e; needles)
if (endsWith!pred(haystack, e))
return i + 1;
return 0;
}


void main(string[] args)
{
string[] test = [1, two, three!];
auto a = arghtwo.endsWithAny(test);
writefln(%s, a);
}

unittest
{
string[] hs = [no-one, thee, there were three, two];
string[] tab = [one, two, three];
assert(endsWithAny(hs[0], tab) == 1);
assert(endsWithAny(hs[1], tab) == 0);
assert(endsWithAny(hs[2], tab) == 3);
assert(endsWithAny(hs[3], tab) == 2);
}


Re: Lexer in D

2013-03-11 Thread FG

On 2013-03-11 16:11, Namespace wrote:

I've also done some benchmarks. And I wonder why my appender is much faster if I
enable memory reservation.


Probably just because D's Appender has a better growth scheme than yours and you 
reallocate too often. Try to compare how often that happens.



I'm also very interested to hear some improvements tips.


Well, you may add a check whether alloc/realloc actually succeeded. :)



Re: How to initialize an immutable array

2013-03-01 Thread FG

I suppose this:

immutable long DIM = 1024L*1024L *128L;
immutable(double)[] signal = new double[DIM+1];
static this() {
for (long i=0L; i DIM+1; i++) {
signal[i] = (i+DIM)%7 + (i+DIM+1)%5;
}
}
void main()
{ ... }



Re: How to initialize an immutable array

2013-03-01 Thread FG

On 2013-03-01 22:05, Sparsh Mittal wrote:

On Friday, 1 March 2013 at 20:28:19 UTC, FG wrote:

I suppose this:

immutable long DIM = 1024L*1024L *128L;
immutable(double)[] signal = new double[DIM+1];
static this() {
for (long i=0L; i DIM+1; i++) {
signal[i] = (i+DIM)%7 + (i+DIM+1)%5;
}
}
void main()
{ ... }


Thanks. This gives an error, which I don't know how to resolve:

Error: cannot evaluate new double[](134217729LU) at compile time

Can you please tell.



Oh, sorry. Was typing without thinking. :)
Here's a working sample (with long changed to uint):


import std.stdio, std.datetime, std.parallelism, std.range;
double my_abs(double n) { return n  0 ? n : -n; }
immutable uint DIM = 1024 * 1024 * 128;
immutable(double)[] signal;

static this() {
auto temp = new double[DIM+1];
for (uint i = 0; i  DIM + 1; i++)
temp[i] = (i + DIM) % 7 + (i + DIM + 1) % 5;
signal = cast(immutable)temp;
}

void main()
{
double temp;
double sample[2] = [4.1,7.2];
StopWatch sw;
sw.start();
for (uint i = 0; i  DIM; i++)
{
temp = my_abs(sample[0]-signal[i])
+ my_abs(sample[1]-signal[i+1]);
}
sw.stop();
writeln( Total time: , (sw.peek().msecs/1000), [sec]);
}




Re: A little of coordination for Rosettacode

2013-02-27 Thread FG

On 2013-02-26 15:10, bearophile wrote:

This third version is much simpler and it seems good enough for
Rosettacode:

http://codepad.org/YJjb1t91


Nice. Myself I'd add bits.reverse; after the N.iota.map..., because I'm more 
used to a truth table where the left-most operands iterate the slowest.




Re: A little of coordination for Rosettacode

2013-02-27 Thread FG

On 2013-02-27 12:47, FG wrote:

On 2013-02-26 15:10, bearophile wrote:

This third version is much simpler and it seems good enough for
Rosettacode:

http://codepad.org/YJjb1t91


Nice. Myself I'd add bits.reverse; after the N.iota.map..., because I'm more
used to a truth table where the left-most operands iterate the slowest.


or, without reverse, but perhaps not very clear:
N.iota.map!(j = !!(i  (1  (N - j - 1.copy(bits[]);



Re: Issues with std.regex

2013-02-16 Thread FG

On 2013-02-16 21:22, MrAppleseed wrote:

auto reg = regex([ 0-9a-zA-Z.*=+-;()\\'\[\],{}^#/\\]);

When I try to run the code above, I get:
parser.d(64): Error: undefined escape sequence \[
parser.d(64): Error: undefined escape sequence \]

When I remove the escaped characters (turning my regex into
[ 0-9a-zA-Z.*=+-;()\\'[],{}^#/\\]), I get no issues compiling or linking.
However, on first run, I get the following error (I cut the error short, full
error is pasted http://pastebin.com/vjMhkx4N):

std.regex.RegexException@/usr/include/dmd/phobos/std/regex.d(1942): wrong
CodepointSet
Pattern with error: `[ 0-9a-zA-Z.*=+-;()'[]` --HERE-- `,{}^#/\]`



Perhaps try this:  [ 0-9a-zA-Z.*=+-;()\\'\\[\\],{}^#/\\]



Re: Issues with std.regex

2013-02-16 Thread FG

On 2013-02-16 22:36, MrAppleseed wrote:

Perhaps try this:  [ 0-9a-zA-Z.*=+-;()\\'\\[\\],{}^#/\\]


I made the changes you suggested above, and although it compiled fine, on the
first run I got a similar error:

std.regex.RegexException@/usr/include/dmd/phobos/std/regex.d(1942): unexpected
end of CodepointSet
Pattern with error: `[ 0-9a-zA-Z.*=+-;()'\[\],{}^#/\]` --HERE-- ``


Ah, right. Sorry for that. You'd need as much as 4 backslashes there. :)
[ 0-9a-zA-Z.*=+-;()\\'\\[\\],{}^#/]

Ain't pretty so it's better to go with raw strings, but apparently there are 
some problems with them right now, looking at the other posts here, right?


Re: Finding large difference b/w execution time of c++ and D codes for same problem

2013-02-13 Thread FG

On 2013-02-13 14:26, Marco Leise wrote:

template Julia(TReal)
{
struct ComplexStruct
{
float r;
float i;
... 


Why aren't r and i of type TReal?


Re: Calculating mean and standard deviation with std.algorithm.reduce

2013-02-13 Thread FG

On 2013-02-13 14:44, Joseph Rushton Wakeling wrote:

The docs for std.algorithm give an illustration of its use to calculate mean and
standard deviation in a single pass: [...]
However, this formula for standard deviation is one that is well known for being
subject to potentially fatal rounding error.


Typical thing with examples - they try to be terse and show off a mechanism like 
reduce, without going into too much details and hence are unusable IRL.


You can use reduce and put the division and subtraction into the reduce itself 
to prevent overflows. You also won't end up with jaw-dropping tuples, sorry. :)


float[] a = [10_000.0f, 10_001.0f, 10_002.0f];
auto n = a.length;
auto avg = reduce!((a, b) = a + b / n)(0.0f, a);
auto var = reduce!((a, b) = a + pow(b - avg, 2) / n)(0.0f, a);
auto sd = sqrt(var);
writeln(avg, \t, sd);

Output: 10001   0.816497


Re: Finding large difference b/w execution time of c++ and D codes for same problem

2013-02-13 Thread FG

Good point about choosing the right type of floating point numbers.
Conclusion: when there's enough space, always pick double over float.
Tested with GDC in win64. floats: 16.0s / doubles: 14.1s / reals: 11.2s.
I thought to myself: cool, I almost beat the 13.4s I got with C++, until I 
changed the C++ code to also use doubles and... got a massive speedup: 7.1s!


Re: Finding large difference b/w execution time of c++ and D codes for same problem

2013-02-13 Thread FG

On 2013-02-13 16:26, Marco Leise wrote:

I'd still bet a dollar that with an array of values floats would
outperform doubles, when cache misses happen. (E.g. more or
less random memory access.)


I'll play it safe and only bet my opDollar. :)



Re: How to read fastly files ( I/O operation)

2013-02-13 Thread FG

On 2013-02-13 18:39, monarch_dodra wrote:

In any case, I am now parsing the 6Gig packed into 1.5Gig in about 53 seconds
(down from 61). I also tried doing a dual-threaded approach (1 thread to unzip,
1 thread to parse), but again, the actual *parse* phase is so ridiculously fast,
that it changes *nothing* to the final result.


Great. Performance aside, we didn't talk much about how this data can be useful 
- should it only be read sequentially forward or both ways, would there be a 
need to place some markers or slice the sequence, etc. Our small test case was 
only about counting nucleotides, so reading order and possibility of further 
processing was irrelevant.


Mr.Bio, what usage cases you'll be interested in, other than those counters?



Re: std.container.RedBlackTree versus C++ std::set

2013-02-13 Thread FG

On 2013-02-14 01:09, Rob T wrote:

You can check if disabling the GC just before the insert process improves the
performance. You may see 3x performance improvement. Disabling is safe provided
you re-enable, this can be done reliably with scope(exit) or something similar.


How did you know? It was 3x in my case. :)
Well, even more but the program had to wait 2 seconds at the end to collect.
With LIMIT at 10M, g++: 5.0s, gdc: 27.0s and 8.7s with GC.disable.
Internal memory handling by containers - yeah, can't wait to see that happen!




Re: Using objects that manage threads via std.concurrency

2013-02-12 Thread FG

On 2013-02-12 12:14, monarch_dodra wrote:

For one thing, MessageBox is private.


Unnecessarily hidden, because, from what I can see from a fast look at the 
sources, there is no implicit requirement for there to be only one MessageBox 
per thread. Maybe we're getting somewhere and this will be changed.



As for the re-implement of receive to work on a custom Tid, maybe it might be
better to forget about the tid, and implement it on directly on the mailbox?


Well, yes. It's more natural to work on mbox than some artificial struct.

Now, as for the usefulness of having many mailboxes. I'd rather have one mailbox 
than go into a loop with receiveTimeout called for each Manager, but in your 
divideconquer example receive makes sense and keeps ordering.


Re: Finding large difference b/w execution time of c++ and D codes for same problem

2013-02-12 Thread FG

On 2013-02-12 21:39, Sparsh Mittal wrote:

I am finding C++ code is much faster than D code.


I had a look, but first had to make juliaValue global, because g++ had optimized 
all the calculations away. :)  Also changed DIM to 32 * 1024.


13.2s -- g++ -O3
16.0s -- g++ -O2
15.9s -- gdc -O3
15.9s -- gdc -O2
16.2s -- dmd -O -release -inline(v.2.060)

Winblows and DMD 32-bit, the rest 64-bit, but still, dmd was quite fast.
Interesting how gdc -O3 gave no extra boost vs. -O2.



Re: Using objects that manage threads via std.concurrency

2013-02-11 Thread FG

On 2013-02-11 22:37, monarch_dodra wrote:

Basically, I can't help but feel the thing has an hopelessly thread-global
mailbox approach to the problem. This is all fine and dandy if there is only a
single canal of communication between the master and the child/children.


What thread-global? Every mbox is in thread-local storage.


But what happens if you have 2 objects at once that want to communicate with
their children? They have to share the global mailbox, making things very 
complex.


Caller locks the callee mailbox for a moment to put a message. Doesn't lock any 
other thread, so you can have N/2 threads writing to other N/2 at the same time.



In my program, I have simple objects: Managers, that spawn a child thread to
do work. This works fine if I have a single Manager, but how do I manage having
2 Managers at once?


It's generally a very bad idea to have more than 1 manager over one's head. :)


What should a manager do if it calls receive, and notices the message wasn't
meant for him?


Don't know. Kill the messenger perhaps? :)




Re: Invisible console

2013-02-10 Thread FG

On 2013-02-10 15:17, SaltySugar wrote:

how to make console invisible?


Seems to be a recurring question here. :)
Search archives. You probably want: dmd.exe -L/SUBSYSTEM:WINDOWS app.d


Re: Looking for writing parallel foreach kind of statement for nested for-loops

2013-02-09 Thread FG

On 2013-02-09 23:32, Sparsh Mittal wrote:

I saw foreach and parallel commands on
http://dlang.org/phobos/std_parallelism.html

I have nested for-loops as follows:

for(int i=1; i N; i++)
  {
   for(int j=1; j  M; j++)
{
  func(i,j);
}
  }

Here func(i,j) is such that there is no dependency or communication b/w
different (i,j) tuple values. Thus, problem is very simple.


Huh?
for(int i=1; i N; i++)==foreach(i; iota(1, N))
so you can use:  foreach(i; parallel(iota(1, N))) { ... }



Re: How to read fastly files ( I/O operation)

2013-02-07 Thread FG

On 2013-02-07 08:26, monarch_dodra wrote:

You have timed the same file SRR077487_1.filt.fastq at 67s?


Yes, that file exactly. That said, I'm working on an SSD, so maybe I'm less IO
bound than you are?


Ah, now that you mention SSD, I moved the file onto one and it's even more
clear that I am CPU-bound here on the Intel E6600 system. Compare:

7200rpm: MS 4m30s / FG 1m55s
SSD: MS 4m14s / FG 1m44s

Almost the same, but running the utility wc -l on the file renders:

7200rpm: 1m45s
SSD: 0m33s

In my case threads would be beneficial but only when using the SSD.
Reading the file by chunk in D takes 33s on SSD and 1m44s on HDD.
Slicing the file in half and reading from both threads would also
be fine only on the SSD, because on a HDD I'd lose sequential disk
reads jumping between threads (expecting lower performance).

Therefore - threads: yes, but gotta use an SSD. :)
Also, threads: yes, if there's gonna be more processing than just
counting letters.


Re: How to read fastly files ( I/O operation)

2013-02-06 Thread FG

On 2013-02-04 15:04, bioinfornatics wrote:

I am looking to parse efficiently huge file but i think D lacking for this 
purpose.
To parse 12 Go i need 11 minutes wheras fastxtoolkit (written in c++ ) need 2 
min.


Haven't compared to fastxtoolkit, but I have some code for you.
I have processed the file SRR077487_1.filt.fastq from
ftp://ftp.1000genomes.ebi.ac.uk/vol1/ftp/data/HG00096/sequence_read/
and expect this syntax (no multiline sequences or whitespace).
File takes up almost 6 GB processing took 1m45s - twice as fast as the
fastest D solution so far -- all compiled with gdc -O3.
I bet your computer has better specs than mine.

Program uses a buffer that should be twice the size of the largest sequence
record (counting id, comment and quality data). A chunk of file is read,
then records are scanned on the buffer until record start pointer passes
the middle of the buffer -- then memcpy is used to move all the rest to
the begining of the buffer and the remaining space at the end is filled with
another chunk read from the file.

Data contains both sequence letter and associated quality information.
Sequence ID and comment are slices of the buffer, so they have valid info
until you move to the next sequence (and the number increments).

This is the code: http://dpaste.1azy.net/8424d4ac
Tell me what timings you can get now.


Re: How to read fastly files ( I/O operation)

2013-02-06 Thread FG

On 2013-02-06 21:43, monarch_dodra wrote:

On Wednesday, 6 February 2013 at 19:19:52 UTC, FG wrote:

I have processed the file SRR077487_1.filt.fastq from
ftp://ftp.1000genomes.ebi.ac.uk/vol1/ftp/data/HG00096/sequence_read/
and expect this syntax (no multiline sequences or whitespace).
File takes up almost 6 GB processing took 1m45s - twice as fast as the
fastest D solution so far


Do you mean my solution above? I tried your solution with dmd, with -release -O
-inline, and both gave about the same result (69s yours, 67s mine).


Yes. Maybe CPU is the bottleneck on my end.
With DMD32 2.060 on win7-64 compiled with same flags I got:
MD: 4m30 / FG: 1m55s - both using 100% of one core.
Quite similar results with GDC64.

You have timed the same file SRR077487_1.filt.fastq at 67s?



I'm getting real interested on the subject. I'm going to try to write an actual
library/framework for working with fastq files in a D environment.


Those fastq are contagious. ;)


This means I'll try to write robust and useable code, with both stability and
performance in mind, as opposed to the proofs of concepts in so far.


Yeah, but the big deal was that D is 5.5x slower than C++.

You have mentioned something about using byLine. Well, I would have gladly used
it instead of looking for line ends myself and pushing stuff with memcpy.
But the thing is that while the fgets(char *buf, int bufSize, FILE *f) in fastx
is fast in reading file by line, using file.readln(buf) is unpredictable. :)
I mean that in DMD it's only a bit slower than file.rawRead(buf), but in GDC
can be several times slower. For example just reading in a loop:

import std.stdio;
enum uint bufferSize = 4096 - 16;
void main(string[] args) {
char[] tmp, buf = new char[bufferSize];
size_t cnt;
auto f = File(args[1], r);
switch(args[2]) {
case raw:
do tmp = f.rawRead(buf); while (tmp.length);
break;

case readln:
do cnt = f.readln(buf); while (cnt);
break;

default: writeln(Use parameters: filename raw|readln);
}
}

Tested on a much smaller SRR077487.filt.fastq:
DMD32 -release -O -inline: raw 94ms / readln 450ms
GDC64 -O3: raw 94ms / readln 6.76s

Tested on SRR077487_1.filt.fastq:
DMD32 -release -O -inline: raw 1m44s / readln  1m55s
GDC64 -O3: raw 1m48s / readln 14m16s

Why such a big difference between the DMD and GDC (on Windows)?
(or have I missed some switch in GDC?)



Re: How to read fastly files ( I/O operation)

2013-02-06 Thread FG

On 2013-02-07 00:41, Lee Braiden wrote:

I wasn't going to mention this as I thought the CPU usage might be trivial, but
if both CPU and IO are factors, then it would probably be beneficial to have a
separate IO thread/task.


This wasn't an issue in my version of the program. It took 1m55s to process the
file, but then again it takes 1m44s just to read it (as shown previously).


Also, if you don't strictly need to parse the file in order, then you could
divide and conquer it by breaking it into more sections/tasks. For example, if
you're parsing records, you cold split the file in half, find the remaining
parts of the record in the second half, move it to the first, and then process
the two halves in two threads.  If you've a nice function to do that split
cleanly, and n cpus, then just call it some more.


Now, this could make a big difference!
If only parsing out of order is acceptable in this case.



Re: GtkD button size

2013-02-05 Thread FG

On 2013-02-05 20:48, SaltySugar wrote:

Can I use hbox.add(btn); instead of hbox.packStart (btn,false,false,5);
What difference between them?


Using add(btn) you would probably end up with a stretched button again. :)
hbox.packStart(child, expand, fill, padding)
It was explicitly said that expand = false, to prevent button resizing.

Read more here:
http://www.mono-project.com/GtkSharp:_Packing_with_Boxes
It's Gtk# but may be of some help to you.


Re: How to read fastly files ( I/O operation)

2013-02-04 Thread FG

On 2013-02-04 15:04, bioinfornatics wrote:

I am looking to parse efficiently huge file but i think D lacking for this 
purpose.
To parse 12 Go i need 11 minutes wheras fastxtoolkit (written in c++ ) need 2 
min.

My code is maybe not easy as is not easy to parse a fastq file and is more
harder when using memory mapped file.


Why are you using mmap? Don't you just go through the file sequentially?
In that case it should be faster to read in chunks:

foreach (ubyte[] buffer; file.byChunk(chunkSize)) { ... }



Re: Why are commands executing out of order?

2013-02-02 Thread FG

On 2013-02-02 07:49, Josh wrote:

But main's first writeln actually outputs after f.close().


Maybe because of output buffering and you need to add flush?


The program uses ~1GB of RAM overall, even though main.results is ~50MB
according to memSize.


Wrong comparison. You should have compared to the output file's size.
info.sizeof doesn't include the size of info.name.
In my test results were 30 MB but the output file was 101 MB.


Any attempts to call the GC do nothing, but I'm probably
doing it wrong though. Is it possible that I have a memory leak somewhere that
is causing this delay, or is this a DMD problem, or something else I haven't
even thought of?


It's a problem with array concatenation and memory fragmentation.
There are two ways out of this mess. First, there's the Unix Way - don't use 
the results array at all and print out info records immediately as they appear. 
Your program will use under 3 MB of RAM. :)


But if you really have to do some extra processing of results, then you can 
reduce the memory used like 6 times by using an Appender instead of 
concatenating arrays and by reserving a reasonable number of records, to limit 
possible initial fragmentation when the array is resized. My program used 145 MB 
whereas the output file was 101 MB. I think it's good enough. But that's 
scanning just one, non-system drive. Won't even try to scan them all.


Try it out:

import std.datetime;
import std.file;
import std.stdio;
import std.array;

struct info
{
string name;
bool isDir;
ulong size;
SysTime timeCreated;
SysTime timeLastAccessed;
SysTime timeLastModified;

this(DirEntry d)
{
this.name = d.name;
this.isDir = d.isDir;
this.size = d.size;
this.timeCreated = d.timeCreated;
this.timeLastAccessed = d.timeLastAccessed;
this.timeLastModified = d.timeLastModified;
}
}

alias Appender!(info[]) InfoAppender;

void main()
{
writeln(Scanning drives...);
info[] results;
InfoAppender app = appender(results);
app.reserve(512*1024);  //
for (char c = 'D'; c = 'D'; c++)
{
if (exists(c ~ :\\))
{
app.put(info(DirEntry(c ~ :\\)));
scan(c ~ :\\, app);
}
}
File f = File(driveInfo.txt, w);
foreach (i; app.data)
{
f.writeln(i);
}
f.close();
writeln(memSize(app.data));
}

void scan(string dir, ref InfoAppender app)
{
try
{
auto de = dirEntries(dir, SpanMode.shallow);
foreach (d; de)
{
app.put(info(d));
if (d.isDir())
scan(d.name, app);
}
}
catch (FileException fe){}
}

size_t memSize(T)(T[] t)
{
return t.length * T.sizeof;
}




And the preferred version to scan whole filesystem without wasting RAM:  :)


import std.datetime;
import std.file;
import std.stdio;

struct info
{
string name;
bool isDir;
ulong size;
SysTime timeCreated;
SysTime timeLastAccessed;
SysTime timeLastModified;

this(DirEntry d)
{
this.name = d.name;
this.isDir = d.isDir;
this.size = d.size;
this.timeCreated = d.timeCreated;
this.timeLastAccessed = d.timeLastAccessed;
this.timeLastModified = d.timeLastModified;
}
}

File f;

void main()
{
writeln(Scanning drives...);
f = File(driveInfo.txt, w);
for (char c = 'D'; c = 'D'; c++)
{
if (exists(c ~ :\\))
{
f.writeln(info(DirEntry(c ~ :\\)));
scan(c ~ :\\);
}
}
f.close();
}

void scan(string dir)
{
try
{
auto de = dirEntries(dir, SpanMode.shallow);
foreach (d; de)
{
f.writeln(info(d));
if (d.isDir())
scan(d.name);
}
}
catch (FileException fe){}
}




Array concatenation vs. Appender

2013-02-02 Thread FG

On 2013-02-02 13:50, Era Scarecrow wrote:

On Saturday, 2 February 2013 at 11:33:07 UTC, Namespace wrote:

I'm was quite surprised as I had heard the first time of these 'appender'.
Therefore I'm asking me:
Why is the 'appender' method so much more efficient?


  Because concatenation likely will end up relocating the memory over and over
again (possibly lots of abandoned slices too) whereas the appender will
allocated  reuse the same buffer. On the other hand you might be better off
(depending on the need) with just reserving a lot more memory (close to what you
need or slightly larger) and then concatenation will perform much better. But if
it need to reallocate then you've still got the same problem with slices where
with the appender you probably won't.


Yeah but let us move reallocation out of the equation.
Reserving space limits the amount of RAM used and can avoid reallocations all 
together but in a little test it came out that still appender is 2.5-4 times 
faster than tab ~= str, where tab is char[] (same when it is ubyte[]). Why is that?


Let's say we have this code:

char[] tab;
string fill = 1234;
uint loops = 100_000_000;
tab.reserve(loops * fill.length);
foreach (i; 0..loops) tab ~= fill;

Using Appender changes the above loop into something like this:

size_t capacity = tab.capacity;
foreach (i; 0..loops) {
size_t flen = fill.length;
size_t len = tab.length;
if (len + flen  capacity) {
...
// use GC.extend or GC.qalloc  memcpy
// update capacity and assign tab = memory_block[0..len]
}
tab = tab.ptr[0..len+flen];
tab.ptr[len..len+flen] = fill[];
}

Why cannot tab ~= fill achieve similar performance as this code?
Am I missing something important?




Re: Why are commands executing out of order?

2013-02-02 Thread FG

On 2013-02-02 16:22, Josh wrote:

Maybe because of output buffering and you need to add flush?


How do I do that? I've never heard of flush before.


writeln(...); stdout.flush();

C also has flush, in the form of fflush(stdout);


I've never come across Appenders before. Could you please explain them a little
bit, and what each call in your modified code does?


I'm baffled myself as to why they perform better than normal array 
concatenation. We'll see if some interesting explanation appears.

That's why I changed the topic to Array concatenation vs. Appender.


Re: Associative Array, key and value as type of string or char[]

2013-02-02 Thread FG

On 2013-02-02 16:06, Namespace wrote:

 string[string] ch_Description = [
 kill : kills a process,
 pause : pauses a process
 ];

 writeln(ch_Description); // does not work, but it should


Doesn't work in the current version? In DMD 2.060 it works.


Re: new T[size] vs .reserve

2013-02-02 Thread FG

On 2013-02-02 19:01, Namespace wrote:

Example:

struct Color {
public:
 ubyte[4] colors;
}

ubyte[] data = new ubyte[color_data.length * 4]; // enough storage
foreach (ref const Color col; color_data) {
 data ~= col.colors;
}


Sorry, but what is the point of data having only 4 bytes reserved
at the beginning? What is wrong with this:

ubyte[] data;
data.reserve(color_data.length * 4);
foreach (ref const Color col; color_data)
data ~= col.colors;

Are you uncomfortable, because it may allocate twice as much space
as you need (for bigger color_data)?


Re: new T[size] vs .reserve

2013-02-02 Thread FG

On 2013-02-02 19:53, Namespace wrote:

Are you uncomfortable, because it may allocate twice as much space
as you need (for bigger color_data)?


Yes, that's the point.
Sorry, I cannot express myself very well in English.


You're right. It's surprising for anyone used to dealing with std::vector,
that it actually reserves more than you specify.

Another odd thing - when pushing back to a vector its capacity grows:
1, 2, 4, 8, 16, 32 ..., but with D arrays it's like 7, 15, 31, 63...
Why 2**n - 1? What secret data is hidden after the block? ;)


Re: new T[size] vs .reserve

2013-02-02 Thread FG

On 2013-02-02 22:57, FG wrote:

On 2013-02-02 22:33, Steven Schveighoffer wrote:

Heap block sizes start at 16.  One byte overhead is used to store the array
length, so the minimum size of ANY array allocation is 15 bytes.


How is the length stored because I see only strange numbers in that byte.

 foreach (end; 2..31) {
 ubyte[] x;
 foreach (i; 0..end) {
 x ~= cast(ubyte)i;
 }
 writeln(x.length,  , x.capacity,  , x.ptr[end]);
 }



Ah, sorry. Silly me.
I have figured out that the length byte would have to be aligned to the end
of the block, so that is where I should look. The updated code:

// size_t ends = [1,2,7,15,31]; // crashes DMD
foreach (end; 2..31) {
ubyte[] x;
foreach (i; 0..end) {
x ~= cast(ubyte)i;
}
writeln(x.length,  , x.capacity,  , x.ptr[x.capacity]);
}
return;

shows that indeed, there's length written at the end. :)
Output:

2 15 2
3 15 3
4 15 4
5 15 5
6 15 6
7 15 7
8 15 8
9 15 9
10 15 10
11 15 11
12 15 12
13 15 13
14 15 14
15 15 15
16 31 16
17 31 17
18 31 18
19 31 19
20 31 20
21 31 21
22 31 22
23 31 23
24 31 24
25 31 25
26 31 26
27 31 27
28 31 28
29 31 29
30 31 30





Re: new T[size] vs .reserve

2013-02-02 Thread FG

On 2013-02-02 22:47, monarch_dodra wrote:

I suggest you read this:
http://dlang.org/d-array-article.html
It is a very interesting read, especially for those of us with C++ background.


Thank you for pointing me to that article.
I have read it months ago and forgotten the important parts.
Now it (slices  arrays) finally started making sense again. :)



Re: Understanding the GC

2013-02-01 Thread FG

On 2013-02-01 16:37, Steven Schveighoffer wrote:

Actually, that's a different problem.  File is a struct, and structs do NOT have
their destructor run by the GC.  Only Objects do.

This is a GC limitation, since structs do not contain a pointer to their
typeinfo like classes do, and there is no provision for storing a pointer to the
typeinfo of a block.  It could be fixed by a more precise GC.  AIUI, we have
something like that coming, but I've been hearing that for more than a year ;)


So currently the only way to make a struct's destructor work when the struct is 
on the heap is to encapsulate that struct in a class?

I have tested the following:

struct A { ... }
class C { A a; ... }

A a = A();   // OK
A *b = new A();  // BAD, no finalization
C c = new C();   // OK, a's destructor will be called


Re: Not able to get scaled performance on increasing number of threads

2013-02-01 Thread FG

On 2013-02-01 16:42, Sparsh Mittal wrote:

When I run it, and compare this parallel version with its serial version, I only
get speedup of nearly 1.3 for 2 threads. When I write same program in Go,
scaling is nearly 2.

Also, in D, on doing top, I see the usage as only 130% CPU and not nearly 200%
or 180%. So I was wondering, if I am doing it properly. Please help me.


Probably because the SolverSlave doesn't have enough work to do to call for 
dividing it into threads and barriers with their overhead. Like Dmitry wrote, 
std.parallelism may be a better tool for the job.


I've tested your code on 2 cores (but have put whole main() in a loop).
It's taking about 82% of both cores.
After increasing gridSize to 1024 it was using 88% of the CPU.


Re: Not able to get scaled performance on increasing number of threads

2013-02-01 Thread FG

On 2013-02-01 20:33, Dmitry Olshansky wrote:

Mine reiteration on it, with a bit of help from std.parallelism.
std.parallelism uses thread pool thus it's somewhat faster then creating threads
anew.


Interestingly, threads+barrier here wasn't much slower than tasks:
14% slower for dmd32, only 5% for gdc64
(and taskpool in dmd 13% slower than in gdc).


Re: How does array assignment for different sized types work?

2013-01-31 Thread FG

On 2013-01-31 10:47, Timon Gehr wrote:

The reason is that array literals have special conversion rules


It's because floating point literals are double by default.
In the first assignment float type can be deduced from v1.
To make the second one work, you can explicitly make them float:

float[3] v1 = [1.0, 2.0, 3.0];
float[3] v = [1.0f, 2.0f, 3.0f].dup;

or duplicate v1:float[3] v = v1.dup;


Re: Looking for command for synchronization of threads

2013-01-31 Thread FG

On 2013-01-31 03:29, Sparsh Mittal wrote:

Thanks. I wrote this:  [...]
It compiles but barrier does not get released. Can you please point out the
fault. Pardon my mistake. I searched whole web, there are almost no examples of
it online.


Barrier doesn't release because you've only called wait() from one thread, while 
initializing the Barrier to use two threads. The following code works for me. 
Notice that the Barrier and wait() are used in 3 threads. But better have this 
verified by someone who had done more threading in D. :)


#!/usr/bin/env rdmd

import std.stdio;
import std.concurrency;
import std.algorithm;
import core.sync.barrier;
import core.thread;

__gshared Barrier barrier = null;

void sorter(Tid owner, shared(int)[] sliceToSort, int mynumber)
{
writefln(Came inside  %s, mynumber);
sort(sliceToSort);
writefln(Going out of %s, mynumber);
barrier.wait();
}

void main()
{
shared numbers = [ 6, 5, 4, 3, 2, 1 ];
barrier = new Barrier(3);
spawn(sorter, thisTid, numbers[0 .. $ / 2], 0);
spawn(sorter, thisTid, numbers[$ / 2 .. $], 1);

writefln(Waiting for barrier in main);
barrier.wait();
writefln(All done);

writeln(numbers);
}



Re: gtkD GUI design

2013-01-31 Thread FG

On 2013-01-31 13:35, SaltySugar wrote:

Thanks, setBorderWidth() is working but button's size isn't changing.


I don't have a working gtk environment to test it, but try this:
(maybe hBox2 isn't even needed and you could vBox.add(algn1);)


import gtk.MainWindow;
import gtk.Label;
import gtk.Button;
import gtk.VBox;
import gtk.HBox;
import gtk.Entry;
import gtk.Main;
import gtk.Alignment;

class Application : MainWindow
{
this()
{
super(GtkD App);
setDefaultSize(200, 200);

HBox hBox = new HBox(false, 3);
HBox hBox1 = new HBox(false, 3);
VBox vBox = new VBox(false, 5);

// Alignment(xalign, yalign, xscale, yscale)
// xscale = 0 stops the child from stretching in X axis
Alignment algn1 = new Alignment(0.5, 0, 0, 0);
HBox hBox2 = new HBox(false, 3);

Button btnLog = new Button(LOGIN ---);
Label lblNick = new Label(User: );
Entry txtNick = new Entry();
Label lblPass = new Label(Password: );
Entry txtPass = new Entry();

btnLog.setSizeRequest(70, 30);
vBox.packStart(hBox, true, true, 3);
vBox.packStart(hBox1, true, true, 3);
vBox.setBorderWidth(8);

hBox.add (lblNick);
hBox.add (txtNick);
hBox1.add (lblPass);
hBox1.add (txtPass);

algn1.add (btnLog);
hBox2.add (algn1);
vBox.add (hBox2);

add(vBox);
showAll();
}
}
void main(string[] args)
{
Main.init(args);
new Application();
Main.run();
}



Re: gtkD GUI design

2013-01-31 Thread FG

On 2013-01-31 14:33, SaltySugar wrote:

I have two more questions;
First, how to remove an arrow on the window's bottom?


By making the window fixed-size, not scalable?


Second, when I run my program it runs together with console. I want to run only
window of application. How to do it?


This has already been asked in this list.
Apparently you have to compile like this:

dmd.exe -L/SUBSYSTEM:WINDOWS app.d



Re: Is there a string remove method, that takes an index

2013-01-30 Thread FG

On 2013-01-30 04:27, Ali Çehreli wrote:

 s = s[0..7] ~ s[8..$];


As with the other slicing approaches, it would be best to check first if 
s.length = i (with i = 8 in this case).




Sorted output from an associative array

2013-01-30 Thread FG

Let's say i have an array: int[string] wordCount.
How to print key:value pairs ordered by descending value?
Or generally how to to store wordCount in an array of structs or type tuples for 
later sorting?


In Python I would use something like this:
sorted(wordCount.items(), key=lambda a: a[1], reverse=True).



Re: Sorted output from an associative array

2013-01-30 Thread FG

Thanks for showing me how to use tuples in this problem.

Just for the record, the sort comparison should be reversed: a  b.


Re: typeid + toString = runtime error

2012-12-30 Thread FG

On 2012-12-30 17:04, Ali Çehreli wrote:

Application error:
core.exception.InvalidMemoryOperationError


My guess is that by the time that destructor is executed, the runtime has been
shut down sufficiently that the ~ operator cannot work.


I've encountered this error before when using ~ in a destructor even without 
shutting down the program. I think the garbage collector by throwing this error 
tries to protect itself by disallowing the creation of any new managed objects 
while a collection is running. Otherwise things would get too complicated. :)




Re: double free or corruption error when using parallel foreach

2012-12-28 Thread FG

On 2012-12-28 01:08, Minas Mina wrote:

Note that there is more code after bool hit = ...
but I didn't include it because the problem is in the trace
function (I commented it out and everything else worked -- apart
from the things are dependent on it of course)


Why don't you show the trace function then? Where's the rest of the code?


[xcb] Unknown request in queue while dequeuing
[xcb] Most likely this is a multi-threaded client and
XInitThreads has not been called
[xcb] Aborting, sorry about that.
raytracing: ../../src/xcb_io.c:178: dequeue_pending_request:
Assertion `!xcb_xlib_unknown_req_in_deq' failed.
bash: line 1: 18982 Aborted (core dumped)
/home/minas/Projects/D/raytracing/raytracing/bin/Release/raytracing


This sheds some light on the problem.
Probably it would go away if only a single thread was made responsible for calls 
into libxcb. That's a preferable, safer approach than initializing for 
multi-threading (but have you done the initializing?).



double free or corruption


IMO that's just a consequence of several threads manipulating same data without 
any locks or synchronization in place.




Re: Running out of memory

2012-12-28 Thread FG

On 2012-12-28 05:41, Jonathan M Davis wrote:

The idea is that if you want to be manually freeing memory, you shouldn't be
using GC memory in the first place. It's unsafe to be freeing it. Let the GC do
that. If you want to manually manage memory, then manually manage it with
malloc and free. If you really need to, then core.memory has the functions for
managing the GC's memory, but you really shouldn't be doing that normally.


I don't require manual malloc. I wanted to make a hint to the GC, that this 
block can be freed, because I know there are no other pointers into it (that 
would be used later), while the imprecise GC finds false pointers and prevents 
the block from being released.


Of course delete is not safe in general, but if the program is designed to 
process data in completely isolated batches, then it shouldn't pose a threat.


GtkD - missing DLLs in Gtk win32 runtime

2012-12-28 Thread FG
I'm trying out the latest GtkD binding. The lib has built without problems, some 
example programs also compile, but I can't run them. The Gtk-Runtime-3.6 archive 
provided at https://github.com/gtkd-developers/GtkD/downloads is missing several 
win32 DLL libraries:


LIBRARY.GLGDK: libgdkglext-win32-3.0-0.dll,
LIBRARY.GLGTK: libgtkglext-win32-3.0-0.dll,
LIBRARY.GDA:   libgda-4.0-4.dll,
LIBRARY.GSV:   libgtksourceview-3.0-0.dll,
LIBRARY.GSTREAMER: libgstreamer-0.10.dll,
LIBRARY.GSTINTERFACES: libgstinterfaces-0.10.dll

I found four of them on the net but can't locate these two anywhere:
libgdkglext-win32-3.0-0.dll and libgtkglext-win32-3.0-0.dll
Please help.


Re: Running out of memory

2012-12-27 Thread FG

On 2012-12-27 15:31, bearophile wrote:

delete is deprecated in D. There is destroy(), and a replacement for delete in
the memory/GC module.


destroy() had no effect on program's behavior, even the docs state that it does 
not initiate a GC cycle or free any GC memory.

So I hope delete will still remain an option.
Very useful for freeing such large chunks like in this example.

What do you mean as the delete replacement?


Re: Running out of memory

2012-12-27 Thread FG

On 2012-12-27 16:14, bearophile wrote:

FG:


What do you mean as the delete replacement?


Take a look here (at free()):

http://dlang.org/phobos/core_memory.html


Oh, I didn't expect this to work on arrays but it does as good as delete:

GC.free(cast(void*)s);



Re: Running out of memory

2012-12-27 Thread FG

On 2012-12-27 16:31, bearophile wrote:

Don't cast arrays arrays to pointers, it's unclean, because dynamic arrays are
two words long. Use the .ptr property:

GC.free(s.ptr);


Things appeared sorted out, but it's not over yet. delete still wins.
Performance-wise free() worked like delete, but there's a nasty glitch.
The following code crashes after a few hundred loops with
core.exception.InvalidMemoryOperationError.

import std.stdio, core.memory;
char[1000] filler = '.';
int fill_times = 1;
void main(string[] args) {
char[] s;
for (int i=0; i  10; i++) {
for (int j=0; j  fill_times; j++)
s ~= filler;
writeln(loop , i + 1, , length: , s.length);
stdout.flush();
// delete s;
GC.free(s.ptr);
s = [];
}
}


Surprisingly, when fill_times = 3736, it always crashes after the 341th loop 
(relies on the filler having 1000 bytes. Some other numbers also trigger it).

What could be responsible for this odd behavior of free()?