Re: Detecting performance pitfall in array access

2020-05-17 Thread Adnan via Digitalmars-d-learn

On Sunday, 17 May 2020 at 09:41:55 UTC, Johan wrote:

On Sunday, 17 May 2020 at 03:30:57 UTC, Adnan wrote:
Hello, I am trying to examine what causes my similar D 
solution to lag behind performance.


In the link, they don't have ldc or gdc but according to my 
machine, the dmd generated code isn't really far behind ldc 
generated code.


https://imgshare.io/image/NN8Xmp


Can you add `--force` to the dub commandline to make sure it is 
rebuilding the executable?


-Johan


The results stay the same. Probably some weird bug in my system.


Re: Detecting performance pitfall in array access

2020-05-17 Thread Adnan via Digitalmars-d-learn

On Sunday, 17 May 2020 at 11:39:30 UTC, kinke wrote:
As a side note, using jagged arrays for multiple dimensions 
should probably be avoided whenever you can.
By jagged array, do you mean vector of vectors? What would be an 
alternative?




Re: Detecting performance pitfall in array access

2020-05-17 Thread kinke via Digitalmars-d-learn

On Sunday, 17 May 2020 at 11:39:30 UTC, kinke wrote:

DMD v2.091:
* dmd -m64 -O -release -boundscheck=off -run ..\speed.d aa bbc: 
~11 μs


I forgot `-inline` for DMD; that reduces the speed, yielding ~16 
μs.


Re: Detecting performance pitfall in array access

2020-05-17 Thread kinke via Digitalmars-d-learn

On Sunday, 17 May 2020 at 03:30:57 UTC, Adnan wrote:
In my machine, if you feed "aa" and "bbc" to the function, ldc 
generated code takes around  400 microseconds. I don't have an 
access to gdc in my machine.


https://imgshare.io/image/NN8Xmp

Full code:
D : https://run.dlang.io/is/vLj7BC
  Nim : https://play.nim-lang.org/#ix=2mhH (for reference)

Compiler flags:
dub : build -b release-nobounds
 nimble : --d:danger


My timings are very different, using LDC v1.21 on Win64:

* ldc2 -O -release -run bla.d aa bbc: 8-9 μs
* ldc2 -O -release -boundscheck=off -run bla.d aa bbc: 8-9 μs
* ldc2 -O -release -boundscheck=off -flto=full 
-defaultlib=phobos2-ldc-lto,druntime-ldc-lto -run bla.d aa bbc: 4 
μs


DMD v2.091:
* dmd -m64 -O -release -boundscheck=off -run ..\speed.d aa bbc: 
~11 μs


As a side note, using jagged arrays for multiple dimensions 
should probably be avoided whenever you can.


Re: Detecting performance pitfall in array access

2020-05-17 Thread Johan via Digitalmars-d-learn

On Sunday, 17 May 2020 at 03:30:57 UTC, Adnan wrote:
Hello, I am trying to examine what causes my similar D solution 
to lag behind performance.


In the link, they don't have ldc or gdc but according to my 
machine, the dmd generated code isn't really far behind ldc 
generated code.


https://imgshare.io/image/NN8Xmp


Can you add `--force` to the dub commandline to make sure it is 
rebuilding the executable?


-Johan



Detecting performance pitfall in array access

2020-05-16 Thread Adnan via Digitalmars-d-learn
Hello, I am trying to examine what causes my similar D solution 
to lag behind performance.


In the link, they don't have ldc or gdc but according to my 
machine, the dmd generated code isn't really far behind ldc 
generated code.


So here is the actual code:

ulong levenshteinEditDistance(T)(in ref T a, in ref T b) if 
(isSomeString!T) {

import std.array : uninitializedArray;

	auto matrix = uninitializedArray!(ulong[][])(a.length + 1, 
b.length + 1);

foreach (i; 0 .. a.length + 1)
matrix[i][0] = i;

foreach (j; 0 .. b.length + 1)
matrix[0][j] = j;

import std.algorithm : min;

for (int i = 1; i < a.length + 1; ++i)
for (int j = 1; j < b.length + 1; ++j) {
const ulong substitutionCost = a[i - 1] == b[j - 1] ? 0 
: 1;
matrix[i][j] = min(matrix[i - 1][j - 1] + 
substitutionCost,
matrix[i][j - 1] + 1, matrix[i - 1][j] 
+ 1);
}

return matrix[a.length][b.length];
}

In my machine, if you feed "aa" and "bbc" to the function, ldc 
generated code takes around  400 microseconds. I don't have an 
access to gdc in my machine.


https://imgshare.io/image/NN8Xmp

Full code:
D : https://run.dlang.io/is/vLj7BC
  Nim : https://play.nim-lang.org/#ix=2mhH (for reference)

Compiler flags:
dub : build -b release-nobounds
 nimble : --d:danger


Re: Associative Array potential performance pitfall?

2020-03-13 Thread H. S. Teoh via Digitalmars-d-learn
On Fri, Mar 13, 2020 at 09:30:16AM -0400, Steven Schveighoffer via 
Digitalmars-d-learn wrote:
> On 3/13/20 5:24 AM, H. S. Teoh wrote:
> > Note that `arg ~ arg` may allocate, but it also may not if the
> > current buffer for `arg` is big enough to accomodate both.
> 
> That always allocates. Only appending may avoid allocation:
> 
> arg ~= arg;

Ah I see.  Mea culpa.


> But, I would instead use ranges if possible to avoid all allocations.
[...]

Initially I thought about avoiding all allocations, but I realized that
no matter what, you need to allocate the key for the AA anyway, so I
didn't go that route.  That said, though, we could probably reduce the
number of allocations by various means, such as having the function
return char[] instead of string, and calling .idup on-demand as opposed
to allocating up-front. This would allow us to reuse a static buffer for
`repeated` instead of incurring an allocation each time.  Given what the
algorithm is doing, this should save some number of allocations if done
correctly.


T

-- 
Creativity is not an excuse for sloppiness.


Re: Associative Array potential performance pitfall?

2020-03-13 Thread Steven Schveighoffer via Digitalmars-d-learn

On 3/13/20 5:24 AM, H. S. Teoh wrote:

Note that `arg ~ arg` may allocate, but it also may not if the current
buffer for `arg` is big enough to accomodate both.


That always allocates. Only appending may avoid allocation:

arg ~= arg;

But, I would instead use ranges if possible to avoid all allocations.

-Steve


Re: Associative Array potential performance pitfall?

2020-03-13 Thread dayllenger via Digitalmars-d-learn

On Friday, 13 March 2020 at 03:40:11 UTC, Adnan wrote:

Where am I losing performance?


It is nonsensical to say without measuring. Humans are 
notoriously bad at predicting performance issues. Wrap all your 
hardworking code into a loop with like 100 iterations, compile 
and run:


$ perf record -g ./app file.txt && perf report

Measure dmd debug build first, then ldc2 -release -O.

Besides what H. S. Teoh said, these things help:

- disable GC before doing the job and enable it afterwards
- use .byLineCopy instead of lines(), it's faster
- use .byKeyValue when printing the results, it's lazy and 
returns both key and value


90ms after vs 215ms before



Re: Associative Array potential performance pitfall?

2020-03-13 Thread H. S. Teoh via Digitalmars-d-learn
On Fri, Mar 13, 2020 at 03:40:11AM +, Adnan via Digitalmars-d-learn wrote:
> In my machine the following D code compiled with release flag and LDC
> performs over 230ms while the similar Go code performs under 120ms.
> 
> string smallestRepr(const string arg) {
>   import std.format : format;
> 
>   const repeated = format!"%s%s"(arg, arg);

.format is dog slow, and not exactly something you want to be calling
every iteration.  Try instead:

auto repeated = arg ~ arg;


>   string result;
>   result.reserve(arg.length);
>   result = arg;

This does not do what you think it does.  Assigning to a string is a
shallow copy; the call to .reserve is superfluous. In fact, it's
triggering another allocation, only to throw it away immediately. Just
write:

auto result = arg;


>   foreach (i; 1 .. arg.length) {
>   const slice = repeated[i .. i + arg.length];
>   if (slice < result)
>   result = slice;
>   }
>   return result;
> }
[...]
> Where am I losing performance?

1) Calling .format -- it's dog slow. Just use ~.

2) Calling .reserve only to throw away the results immediately. Just
skip it.

I doubt your AA is the performance bottleneck here.


Try the following implementation of .smallestRepr that avoids (1) and
(2):

string smallestRepr(const string arg) {
auto repeated = arg ~ arg;
string result = arg;
foreach (i; 1 .. arg.length) {
const slice = repeated[i .. i + arg.length];
if (slice < result)
result = slice;
}
return result;
}

Note that `arg ~ arg` may allocate, but it also may not if the current
buffer for `arg` is big enough to accomodate both. So you might actually
save on some allocations here, that you lose out from calling .format.

On my machine, a quick benchmark shows a 2x performance boost.


T

-- 
That's not a bug; that's a feature!


Associative Array potential performance pitfall?

2020-03-12 Thread Adnan via Digitalmars-d-learn
In my machine the following D code compiled with release flag and 
LDC performs over 230ms while the similar Go code performs under 
120ms.


string smallestRepr(const string arg) {
import std.format : format;

const repeated = format!"%s%s"(arg, arg);
string result;
result.reserve(arg.length);
result = arg;
foreach (i; 1 .. arg.length) {
const slice = repeated[i .. i + arg.length];
if (slice < result)
result = slice;
}
return result;
}

unittest {
assert("cba".smallestRepr() == "acb");
}

void main(const string[] args) {
string[][const string] wordTable;
import std.stdio : writeln, lines, File;

foreach (string word; File(args[1]).lines()) {
word = word[0 .. $ - 1]; // strip the newline character
const string key = word.smallestRepr();
if (key in wordTable)
wordTable[key] ~= word;
else
wordTable[key] = [word];
}

foreach (key; wordTable.keys) {
if (wordTable[key].length == 4) {
writeln(wordTable[key]);
break;
}
}
}

---

package main

import (
"bufio"
"fmt"
"os"
)

func canonicalize(s string) string {
c := s + s[:len(s)-1]
best := s
for i := 1; i < len(s); i++ {
if c[i:i+len(s)] < best {
best = c[i : i+len(s)]
}
}
return best
}

func main() {
seen := make(map[string][]string)

inputFile, err := os.Open(os.Args[1])
defer inputFile.Close()

if err != nil {
os.Exit(1)
}

scanner := bufio.NewScanner(inputFile)

for scanner.Scan() {
word := scanner.Text()
n := canonicalize(word)
seen[n] = append(seen[n], word)

}

for _, words := range seen {
if len(words) == 4 {
fmt.Printf("%v\n", words)
break
}

}
}

The input file : 
https://raw.githubusercontent.com/dolph/dictionary/master/enable1.txthttps://raw.githubusercontent.com/dolph/dictionary/master/enable1.txt


Problem description: 
https://www.reddit.com/r/dailyprogrammer/comments/ffxabb/20200309_challenge_383_easy_necklace_matching


Where am I losing performance?


Re: delegates, lambdas and functions pitfall

2016-09-05 Thread dom via Digitalmars-d-learn
On Monday, 5 September 2016 at 12:32:49 UTC, Lodovico Giaretta 
wrote:

On Monday, 5 September 2016 at 12:15:35 UTC, dom wrote:

[...]


You misunderstood the error message and the lambda syntax (it 
also happened to me the first time).


The grammar says that you can use one of these syntaxes:

1) `(arguments) {block of code}`

2) `(arguments) => expression`, which is equivalent to 
`(arguments) {return expression;}`


3) `{block of code}`, which is equivalent to `(){block of 
code}`.


So if you write `(arguments) => {block of code}`, this is 
equivalent to (see rule 2) `(arguments) { return {block of 
code}; }`.


And because of rule 3, it becomes `(arguments) { return 
(){block of code} }`. So what you have is a function that 
returns a function. That's why it does not match your signature.


The fact that the compiler also adds nothrow, @nogc, @safe is 
not important in this case, as those attributes can be 
implicitly casted away.


thank you for that detailed answer.




Re: delegates, lambdas and functions pitfall

2016-09-05 Thread dom via Digitalmars-d-learn

On Monday, 5 September 2016 at 12:30:37 UTC, Daniel Kozak wrote:



Dne 5.9.2016 v 14:15 dom via Digitalmars-d-learn napsal(a):

...
but what is the difference between a lambda (=>) and a 
functions/delegates?
i think this is a major pitfall for newcomers, and should be 
adressed somehow.

Yes, RTFM :)


yes you are right, but laziness you know :D

those pages aren't especially beginner friendly x)
https://dlang.org/spec/expression.html#Lambda


Re: delegates, lambdas and functions pitfall

2016-09-05 Thread Lodovico Giaretta via Digitalmars-d-learn

On Monday, 5 September 2016 at 12:15:35 UTC, dom wrote:

[...]


You misunderstood the error message and the lambda syntax (it 
also happened to me the first time).


The grammar says that you can use one of these syntaxes:

1) `(arguments) {block of code}`

2) `(arguments) => expression`, which is equivalent to 
`(arguments) {return expression;}`


3) `{block of code}`, which is equivalent to `(){block of code}`.

So if you write `(arguments) => {block of code}`, this is 
equivalent to (see rule 2) `(arguments) { return {block of code}; 
}`.


And because of rule 3, it becomes `(arguments) { return (){block 
of code} }`. So what you have is a function that returns a 
function. That's why it does not match your signature.


The fact that the compiler also adds nothrow, @nogc, @safe is not 
important in this case, as those attributes can be implicitly 
casted away.


Re: delegates, lambdas and functions pitfall

2016-09-05 Thread Daniel Kozak via Digitalmars-d-learn

Dne 5.9.2016 v 14:30 Daniel Kozak napsal(a):




Dne 5.9.2016 v 14:15 dom via Digitalmars-d-learn napsal(a):

...
but what is the difference between a lambda (=>) and a 
functions/delegates?
i think this is a major pitfall for newcomers, and should be adressed 
somehow.

Yes, RTFM :)

But to be fair I have made this mistake myself many times :)


Re: delegates, lambdas and functions pitfall

2016-09-05 Thread Daniel Kozak via Digitalmars-d-learn



Dne 5.9.2016 v 14:15 dom via Digitalmars-d-learn napsal(a):

...
but what is the difference between a lambda (=>) and a 
functions/delegates?
i think this is a major pitfall for newcomers, and should be adressed 
somehow.

Yes, RTFM :)


Re: delegates, lambdas and functions pitfall

2016-09-05 Thread Daniel Kozak via Digitalmars-d-learn

Dne 5.9.2016 v 14:15 dom via Digitalmars-d-learn napsal(a):

I am about to write my own stupid and simple http client .. and i have 
added a callback function that has the received content as a parameter.


class AsyncHttpGet
{
this(string host, ushort port, string path, void delegate(string) 
callback )

{ ... }
}

My first attempt was to write:

auto f = new AsyncHttpGet("www.dprogramming.com", 80, "/index.php", 
(string content) => {

  ...
});

but this is does not work because my AsyncHttpGet takes a normal 
delegate and this => seems to add nothrow @nogc @safe to my delegate 
type.


The correct syntax is only marginally differnt, but took me quite a 
while to figure out:

( the missing arrow )

auto f = new AsyncHttpGet("www.dprogramming.com", 80, "/index.php", 
(string content)

{
 ... // this is of type function
});

i noticed that delegates are "more powerful" than functions. once the 
passed function e.g. needs to capture a value from the outside it 
becomes a delegate type. I have also read that a delegate can contain 
a reference to a class method bound to an instance.


int dummy = 0;
auto f = new AsyncHttpGet("www.dprogramming.com", 80, "/index.php", 
(string content)

{
 dummy = 1; // this is of type delegate
});

but what is the difference between a lambda (=>) and a 
functions/delegates?
i think this is a major pitfall for newcomers, and should be adressed 
somehow.


(string content) => { } // this is delegate which returns another 
delegates {} is shorthand here for (){}


when you use => syntax you can just return expression

(string content) => content; is same as (string content) { return content; }




delegates, lambdas and functions pitfall

2016-09-05 Thread dom via Digitalmars-d-learn
I am about to write my own stupid and simple http client .. and i 
have added a callback function that has the received content as a 
parameter.


class AsyncHttpGet
{
this(string host, ushort port, string path, void 
delegate(string) callback )

{ ... }
}

My first attempt was to write:

auto f = new AsyncHttpGet("www.dprogramming.com", 80, 
"/index.php", (string content) => {

  ...
});

but this is does not work because my AsyncHttpGet takes a normal 
delegate and this => seems to add nothrow @nogc @safe to my 
delegate type.


The correct syntax is only marginally differnt, but took me quite 
a while to figure out:

( the missing arrow )

auto f = new AsyncHttpGet("www.dprogramming.com", 80, 
"/index.php", (string content)

{
 ... // this is of type function
});

i noticed that delegates are "more powerful" than functions. once 
the passed function e.g. needs to capture a value from the 
outside it becomes a delegate type. I have also read that a 
delegate can contain a reference to a class method bound to an 
instance.


int dummy = 0;
auto f = new AsyncHttpGet("www.dprogramming.com", 80, 
"/index.php", (string content)

{
 dummy = 1; // this is of type delegate
});

but what is the difference between a lambda (=>) and a 
functions/delegates?
i think this is a major pitfall for newcomers, and should be 
adressed somehow.


Re: Garbage Collection Pitfall in C++ but not in D?

2012-07-07 Thread David Nadlinger

On Saturday, 7 July 2012 at 03:02:07 UTC, akaz wrote:

On Friday, 6 July 2012 at 21:10:56 UTC, Simon wrote:

On 06/07/2012 16:39, Alex Rønne Petersen wrote:
Never mind what D says, even in C/C++ just doing the p += 10 
is invalid.


Creating a pointer that points at invalid memory is just as 
wrong as dereferencing it would be.


Actually, p+10 could still be valid memory.


Not if p+10 was not allocated as part of the same block as p was 
(i.e. if p is the result of »new int«, it is always illegal). 
It might »physically« work with the common C/D implementations 
if another chunk of your memory is at that address, just as 
*(cast(int*)0xdeadbeef) could potentially work, but it is 
undefined behavior by the rules of the language. If the compiler 
can prove that when allocating the memory p points at, p + 10 was 
not allocated as well, it would even be free to directly replace 
a read from that pointer with an undefined value.


David


Re: Garbage Collection Pitfall in C++ but not in D?

2012-07-06 Thread Alex Rønne Petersen

On 07-07-2012 05:02, akaz wrote:

On Friday, 6 July 2012 at 21:10:56 UTC, Simon wrote:

On 06/07/2012 16:39, Alex Rønne Petersen wrote:

On 06-07-2012 16:07, Denis Shelomovskij wrote:

06.07.2012 17:43, akaz пишет:


Never mind what D says, even in C/C++ just doing the p += 10 is invalid.

Creating a pointer that points at invalid memory is just as wrong as
dereferencing it would be.


Actually, p+10 could still be valid memory.

OTOH, the other case that's given on the original page is this one:

 int* p = new int;
 int x = reinterpret_cast(p);// non-portable


This will fail on a 64-bit system, but


 p=0;


will work fine on a 32-bit system since the pointer is still 
conservatively visible in x. Not many GCs scan the stack and static data 
segments precisely, since it's often not worth it. This is the case for 
D's GC.


(Make x size_t and it will always work. In D, anyway.)


 // ... collector may run here ...
 p = reinterpret_cast(x);
 *p = 10;// can we be sure that the int is still there?


Yes (under the conditions described above).



So, the pointer could sometimes simply disappear temporarily, without
becoming invalid (well, p==NULL is somewhat invalid, bt it could have
been p=&q). Just some allocated memory is no longer referenced for the
time being and this could trigger the GC without protection (except
disabling GC for the entire application).

Won't some functions doing just what addRange() and removeRange() do
solve that kind of problem (if necessary)? That means, forbidding the GC
to scan some memory area for some time?


I think you misunderstand what those functions do. See my earlier reply. 
addRange() merely lets the GC know that a region of memory may contain 
pointers into GC memory on every machine word boundary of the region. 
This region of memory is scanned conservatively, i.e. an integer inside 
the region which looks like a pointer will keep the memory that the 
pointer value would point into alive. The stack is always scanned by the 
GC, and in D's case, conservatively. removeRange() just removes a root 
memory range; no magic there.


--
Alex Rønne Petersen
a...@lycus.org
http://lycus.org




Re: Garbage Collection Pitfall in C++ but not in D?

2012-07-06 Thread akaz
Won't some functions doing just what addRange() and 
removeRange() do solve that kind of problem (if necessary)? 
That means, forbidding the GC to scan some memory area for some 
time?


Like their C++11 counterparts:

	void declare_reachable(void* p);	// the region of memory 
starting at p

// (and allocated by some 
allocator
// operation which remembers 
its size)
// must not be collected
template T* undeclare_reachable(T* p);

	void declare_no_pointers(char* p, size_t n);	   // p[0..n] holds 
no pointers

void undeclare_no_pointers(char* p, size_t n);




Re: Garbage Collection Pitfall in C++ but not in D?

2012-07-06 Thread akaz

On Friday, 6 July 2012 at 21:10:56 UTC, Simon wrote:

On 06/07/2012 16:39, Alex Rønne Petersen wrote:

On 06-07-2012 16:07, Denis Shelomovskij wrote:

06.07.2012 17:43, akaz пишет:


Never mind what D says, even in C/C++ just doing the p += 10 is 
invalid.


Creating a pointer that points at invalid memory is just as 
wrong as dereferencing it would be.


Actually, p+10 could still be valid memory.

OTOH, the other case that's given on the original page is this 
one:


int* p = new int;
int x = reinterpret_cast(p); // non-portable
p=0;
// ... collector may run here ...
p = reinterpret_cast(x);
*p = 10;// can we be sure that the int is still there?

So, the pointer could sometimes simply disappear temporarily, 
without becoming invalid (well, p==NULL is somewhat invalid, bt 
it could have been p=&q). Just some allocated memory is no longer 
referenced for the time being and this could trigger the GC 
without protection (except disabling GC for the entire 
application).


Won't some functions doing just what addRange() and removeRange() 
do solve that kind of problem (if necessary)? That means, 
forbidding the GC to scan some memory area for some time?


Re: Garbage Collection Pitfall in C++ but not in D?

2012-07-06 Thread Simon

On 06/07/2012 16:39, Alex Rønne Petersen wrote:

On 06-07-2012 16:07, Denis Shelomovskij wrote:

06.07.2012 17:43, akaz пишет:

Hi,

Reading about the C++11, I stumbled upon this:

http://www2.research.att.com/~bs/C++0xFAQ.html#gc-abi

Specifically (quote):

int* p = new int;
p+=10;
// ... collector may run here ...
p-=10;
*p = 10; // can we be sure that the int is still there?

How does the D garbage collector solves (answers) that?

Thank you.


If you are interested in D read this first:
http://dlang.org/garbage.html

You can find there e.g.:
 > Do not add or subtract an offset to a pointer such that the result
points outside of the bounds of the garbage collected object originally
allocated.

So `p+=10;` is already "undefined behavior".



I'll just add: Handling this case is basically impossible to do sanely.
You can't really know what some pointer off the bounds of a managed
memory region is based on. It could literally be based on any memory
region in the entire program. You could do heuristics of course, but . . .



Never mind what D says, even in C/C++ just doing the p += 10 is invalid.

Creating a pointer that points at invalid memory is just as wrong as 
dereferencing it would be. The possible crash on the dereference of the 
pointer is just the symptom of the under lying bug.


With visual studio & their implementation of the std containers, in a 
debug build if you increment/decrement or otherwise create an iterator 
that's outside the allowable bounds of the container you get a runtime 
assertion failure.


It's a very handy feature and uncovered a load of bugs when we upgraded 
to VS 2008.


--
My enormous talent is exceeded only by my outrageous laziness.
http://www.ssTk.co.uk




Re: Garbage Collection Pitfall in C++ but not in D?

2012-07-06 Thread Alex Rønne Petersen

On 06-07-2012 22:07, akaz wrote:

On Friday, 6 July 2012 at 15:39:40 UTC, Alex Rønne Petersen wrote:

On 06-07-2012 16:07, Denis Shelomovskij wrote:

06.07.2012 17:43, akaz пишет:

Hi,

Reading about the C++11, I stumbled upon this:



I'll just add: Handling this case is basically impossible to do
sanely. You can't really know what some pointer off the bounds of a
managed memory region is based on. It could literally be based on any
memory region in the entire program. You could do heuristics of
course, but . . .


Is not possible to make use of addRange() and removeRange() to "block"
the GC over a specified time/range?


Those just add root ranges, i.e. areas of memory that will be scanned 
for [interior] pointers during the marking phase. It still won't solve 
the problem.


You can disable the GC entirely with GC.disable().

--
Alex Rønne Petersen
a...@lycus.org
http://lycus.org




Re: Garbage Collection Pitfall in C++ but not in D?

2012-07-06 Thread akaz
On Friday, 6 July 2012 at 15:39:40 UTC, Alex Rønne Petersen 
wrote:

On 06-07-2012 16:07, Denis Shelomovskij wrote:

06.07.2012 17:43, akaz пишет:

Hi,

Reading about the C++11, I stumbled upon this:



I'll just add: Handling this case is basically impossible to do 
sanely. You can't really know what some pointer off the bounds 
of a managed memory region is based on. It could literally be 
based on any memory region in the entire program. You could do 
heuristics of course, but . . .


Is not possible to make use of addRange() and removeRange() to 
"block" the GC over a specified time/range?


Re: Garbage Collection Pitfall in C++ but not in D?

2012-07-06 Thread Timon Gehr

On 07/06/2012 05:39 PM, Alex Rønne Petersen wrote:

On 06-07-2012 16:07, Denis Shelomovskij wrote:

06.07.2012 17:43, akaz пишет:

Hi,

Reading about the C++11, I stumbled upon this:

http://www2.research.att.com/~bs/C++0xFAQ.html#gc-abi

Specifically (quote):

int* p = new int;
p+=10;
// ... collector may run here ...
p-=10;
*p = 10; // can we be sure that the int is still there?

How does the D garbage collector solves (answers) that?

Thank you.


If you are interested in D read this first:
http://dlang.org/garbage.html

You can find there e.g.:
> Do not add or subtract an offset to a pointer such that the result
points outside of the bounds of the garbage collected object originally
allocated.

So `p+=10;` is already "undefined behavior".



I'll just add: Handling this case is basically impossible to do sanely.
You can't really know what some pointer off the bounds of a managed
memory region is based on. It could literally be based on any memory
region in the entire program. You could do heuristics of course, but . . .



You could run the program in a dedicated VM. :)


Re: Garbage Collection Pitfall in C++ but not in D?

2012-07-06 Thread Alex Rønne Petersen

On 06-07-2012 16:07, Denis Shelomovskij wrote:

06.07.2012 17:43, akaz пишет:

Hi,

Reading about the C++11, I stumbled upon this:

http://www2.research.att.com/~bs/C++0xFAQ.html#gc-abi

Specifically (quote):

int* p = new int;
p+=10;
// ... collector may run here ...
p-=10;
*p = 10; // can we be sure that the int is still there?

How does the D garbage collector solves (answers) that?

Thank you.


If you are interested in D read this first:
http://dlang.org/garbage.html

You can find there e.g.:
 > Do not add or subtract an offset to a pointer such that the result
points outside of the bounds of the garbage collected object originally
allocated.

So `p+=10;` is already "undefined behavior".



I'll just add: Handling this case is basically impossible to do sanely. 
You can't really know what some pointer off the bounds of a managed 
memory region is based on. It could literally be based on any memory 
region in the entire program. You could do heuristics of course, but . . .


--
Alex Rønne Petersen
a...@lycus.org
http://lycus.org


Re: Garbage Collection Pitfall in C++ but not in D?

2012-07-06 Thread akaz


If you are interested in D read this first:
http://dlang.org/garbage.html

You can find there e.g.:
> Do not add or subtract an offset to a pointer such that the
result points outside of the bounds of the garbage collected 
object originally allocated.


So `p+=10;` is already "undefined behavior".


Thank you, this clear the issue.





Re: Garbage Collection Pitfall in C++ but not in D?

2012-07-06 Thread Denis Shelomovskij

06.07.2012 17:43, akaz пишет:

Hi,

  Reading about the C++11, I stumbled upon this:

  http://www2.research.att.com/~bs/C++0xFAQ.html#gc-abi

  Specifically (quote):

  int* p = new int;
 p+=10;
 // ... collector may run here ...
 p-=10;
 *p = 10;// can we be sure that the int is still there?

  How does the D garbage collector solves (answers) that?

Thank you.


If you are interested in D read this first:
http://dlang.org/garbage.html

You can find there e.g.:
> Do not add or subtract an offset to a pointer such that the result 
points outside of the bounds of the garbage collected object originally 
allocated.


So `p+=10;` is already "undefined behavior".

--
Денис В. Шеломовский
Denis V. Shelomovskij




Garbage Collection Pitfall in C++ but not in D?

2012-07-06 Thread akaz

Hi,

 Reading about the C++11, I stumbled upon this:

 http://www2.research.att.com/~bs/C++0xFAQ.html#gc-abi

 Specifically (quote):

int* p = new int;
p+=10;
// ... collector may run here ...
p-=10;
*p = 10;// can we be sure that the int is still there?

 How does the D garbage collector solves (answers) that?

Thank you.


Re: Pitfall

2012-02-06 Thread David Nadlinger

On 2/6/12 8:23 PM, Timon Gehr wrote:

On 02/06/2012 08:20 PM, Manfred Nowak wrote:

Today I got the nice message

Error: undefined identifier missing

from DMD2.057/win and was baffled for several minutes until I
recognized the meaning.

-manfred


Single quotes would indeed be helpful.


I feel that several of DMD's error messages could use punctuation and 
»proper« casing…


David


Re: Pitfall

2012-02-06 Thread Timon Gehr

On 02/06/2012 08:20 PM, Manfred Nowak wrote:

Today I got the nice message

 Error: undefined identifier missing

from DMD2.057/win and was baffled for several minutes until I
recognized the meaning.

-manfred


Single quotes would indeed be helpful.


Pitfall

2012-02-06 Thread Manfred Nowak
Today I got the nice message

Error: undefined identifier missing

from DMD2.057/win and was baffled for several minutes until I 
recognized the meaning.

-manfred