Implementing Template Restrictions in Different Way
Forgetting to do import std.functional: binaryFun; before trying to compile bool skipOverSafe(alias pred = "a == b", R1, R2)(ref R1 r1, R2 r2) @safe pure if (is(typeof(binaryFun!pred(r1.front, r2.front { return r1.length >= r2.length && skipOver!pred(r1, r2); // TODO: Can we prevent usage of .length? } unittest { auto s1 = "Hello world"; assert(!skipOverSafe(s1, "Ha")); } gives no clue about the missing import in the diagnostics. Is this a other/newer preferred way to describe the template restriction, using for example __traits(compiles, ...)? Is is(typeof(... the fastest way to do this? BTW: Is there a way to prevent the calls to r1.length and r2.length in this case?
Query Parser Callstack
Are there some nice traits or internals to query the current call stack for address or perhaps even their (mangled) names. I'm mostly interested in using this to detect infinite recursions in my recursive descent parser. This provided that my parser slice hasn't changed since last call to the same function.
Re: Programming a Game in D? :D
On Monday, 1 September 2014 at 17:24:10 UTC, rcor wrote: Just wanted to point out that there are also D bindings for Allegro5 (https://github.com/SiegeLord/DAllegro5). Allegro is a bit like SDL or SFML, but personally I find it a bit more intuitive. I've been using the D bindings for about a month and they seem to work fine. Most Allegro tutorials are for C/C++, but they're not too hard to translate -- all of the allegro functions/structs work almost identically in D as they do in C. That is just overkill. Problem with these libraries is that David now has to go compile everyone and their mother from scratch. Lets face it, nobody wants to waste their time on that... My recommendation is GFM "http://code.dlang.org/packages/gfm";, sure it may not be full featured but at least it gets the job done and without the need for compiling. Just add GFM modules to dub.json "gfm:core": ">=0.0.0", "gfm:math": ">=0.0.0", "gfm:image": ">=0.0.0", "gfm:sdl2": ">=0.0.0", "gfm:opengl": ">0.0.0", "gfm:freeimage": ">0.0.0"
Re: basic question about adresses and values in structs
On 09/01/2014 11:23 AM, nikki wrote: ah so much cleaner then the mess I was almost into ;) thanks In case they are useful to you or somebody else, the following chapters are relevant. Value Types and Reference Types: http://ddili.org/ders/d.en/value_vs_reference.html Pointers: http://ddili.org/ders/d.en/pointers.html Ali
Re: basic question about adresses and values in structs
ah so much cleaner then the mess I was almost into ;) thanks
Re: basic question about adresses and values in structs
On Monday, 1 September 2014 at 18:08:48 UTC, nikki wrote: so I am still very new to structs and & and * adress and pointer stuff, I have this basic code : struct S { int value = 0; } void func(S thing){ writeln(&thing); //BFC52B44 thing.value = 100; } S guy = {value:200}; writeln(&guy); //BFC52CCC func(guy); writeln(guy.value);// this prints 200, because the adress was not the same I think I see whats going on but I don't know how to fix it? void func(ref S thing){ writeln(&thing); thing.value = 100; } The ref keyword passes the variable into the function by reference, so that it is not copied.
Re: basic question about adresses and values in structs
sorry could have quicker just googled it thanks!
basic question about adresses and values in structs
so I am still very new to structs and & and * adress and pointer stuff, I have this basic code : struct S { int value = 0; } void func(S thing){ writeln(&thing); //BFC52B44 thing.value = 100; } S guy = {value:200}; writeln(&guy); //BFC52CCC func(guy); writeln(guy.value);// this prints 200, because the adress was not the same I think I see whats going on but I don't know how to fix it?
Re: Programming a Game in D? :D
Also, regarding comments about Garbage Collection -- yes, it could be an issue, but its not a showstopper. C# (which has a GC) was widely used to create PC and 360 games with the XNA library (which lives on as MonoGame). If you have a real time game that manages many objects at once, you may have to be careful about allocating/freeing resources and resort to methods like object pooling (reusing objects rather than destroying them and creating new ones), but it should be doable.
Re: Programming a Game in D? :D
Just wanted to point out that there are also D bindings for Allegro5 (https://github.com/SiegeLord/DAllegro5). Allegro is a bit like SDL or SFML, but personally I find it a bit more intuitive. I've been using the D bindings for about a month and they seem to work fine. Most Allegro tutorials are for C/C++, but they're not too hard to translate -- all of the allegro functions/structs work almost identically in D as they do in C.
Re: D1: Error: duplicate union initialization for size
On Sunday, 31 August 2014 at 03:06:48 UTC, Dicebot wrote: My guess is that it hasn't been ported to the D1 compiler yet. Dicebot or any other people who work for Sociomantic should be most helpful. At this point, I recommend that you ask on the main D forum. Ali I have not encountered such issue in our D1 codebase but I will forward this question to our internal chat on Monday Have asked, no immediate recognition, sorry.
Re: Loading Symbols from Loaded Libraries
On Monday, 1 September 2014 at 13:31:32 UTC, Matt wrote: If I were to use Runtime.loadLibrary(), it claims to merge any D GC in the shared lib with the current process' GC. Do I need to version away symbol loading code for each platform? Or is there already code in Phobos that allows us to do this independent of platform? There was high level Library wrapper by Martin Nowak ( https://github.com/MartinNowak/druntime/commit/f8f512edea2370759ab75703dceece5e069645be ), but it seems it was not added to main dmd repository. So you should use dlsym / GetProcAddress. Use core.demangle.mangle to get mangled names of D functions. I also made some similar wrapper in my project https://bitbucket.org/FreeSlave/dido But it was not updated for a long time and now it's outdated (code uses dlopen and LoadLibrary which is wrong and should be changed to Runtime.loadLibrary. Same for dlclose and FreeLibrary)
Loading Symbols from Loaded Libraries
If I were to use Runtime.loadLibrary(), it claims to merge any D GC in the shared lib with the current process' GC. Do I need to version away symbol loading code for each platform? Or is there already code in Phobos that allows us to do this independent of platform?
Re: alias and mixin
On Mon, 01 Sep 2014 11:56:33 + evilrat via Digitalmars-d-learn wrote: > and D states "intuitive is the way", yeah... it's still way better than C++. ;-) signature.asc Description: PGP signature
Re: A significant performance difference
On Mon, 01 Sep 2014 09:16:04 + bearophile via Digitalmars-d-learn wrote: > https://issues.dlang.org/show_bug.cgi?id=13410 ah, silly me. i should stop publish patches until i rewrote 'em at least three times. we have a winner now: new patch should not hurt AA performance in normal use cases yet our cases are now significantly faster (3 to 3000 times, yeah! ;-). signature.asc Description: PGP signature
Re: alias and mixin
On Monday, 1 September 2014 at 11:23:37 UTC, ketmar via Digitalmars-d-learn wrote: On Mon, 01 Sep 2014 10:57:41 + evilrat via Digitalmars-d-learn wrote: p.s. you should really read about D mixins and templates. they aren't such intuitive sometimes, has their set of funny restrictions, and it may be hard to 'guess the right way' sometimes. but to be honest, i wasn't read any books and found alot of things by experimenting, so it's not a dead-end way too. ;-) thanks again, i also made tweaks to my original template to check for aliases and now it works too, means that error message was totally misleading. btw i had read some articles about mixins and templates but still difference between template and mixin template is somewhat confusing. and D states "intuitive is the way", yeah...
Re: A significant performance difference
The following D code runs over 2x faster than the C++ code (comparing dmd no options to g++ no options.) Its not a fair comparison because it changes the order of operations. import core.stdc.stdio; const uint H = 9, W = 12; const uint[3][6] g = [[7, 0, H - 3], [1 + (1 << H) + (1 << (2 * H)), 0, H - 1], [3 + (1 << H), 0, H - 2], [3 + (2 << H), 0, H - 2], [1 + (1 << H) + (2 << H), 0, H - 2], [1 + (1 << H) + (1 << (H - 1)), 1, H - 1]]; int main() { ulong p, i, k; ulong[uint] x, y; uint l; x[0] = 1; for (i = 0; i < W; ++i) { y = null; while (x.length) foreach (j; x.keys) { p = x[j]; x.remove(j); for (k = 0; k < H; ++k) if ((j & (1 << k)) == 0) break; if (k == H) y[j >> H] += p; else for (l = 0; l < 6; ++l) if (k >= g[l][1] && k <= g[l][2]) if ((j & (g[l][0] << k)) == 0) x[j + (g[l][0] << k)] += p; } x = y; } printf("%lld\n", y[0]); return 0; }
Re: A significant performance difference
On Mon, 01 Sep 2014 09:16:04 + bearophile via Digitalmars-d-learn wrote: > https://issues.dlang.org/show_bug.cgi?id=13410 added another version of the patch. it doesn't significantly improves your original code execution time, but makes syntetic tests runs with the same speed. aa.remove() is little slower now, but i don't think that it's even noticable. but now we can use AAs in 'take first item and immideately remove it' scenarios without performance hit. signature.asc Description: PGP signature
Re: alias and mixin
On Mon, 01 Sep 2014 10:57:41 + evilrat via Digitalmars-d-learn wrote: p.s. you should really read about D mixins and templates. they aren't such intuitive sometimes, has their set of funny restrictions, and it may be hard to 'guess the right way' sometimes. but to be honest, i wasn't read any books and found alot of things by experimenting, so it's not a dead-end way too. ;-) signature.asc Description: PGP signature
Re: alias and mixin
On Mon, 01 Sep 2014 10:57:41 + evilrat via Digitalmars-d-learn wrote: and to check that ugly hackery: mixin template makeAlias(string aliasName, string Name, alias Replace) { static if ( __traits(compiles, (mixin(Name~`.sizeof`))) ) mixin(`alias `~aliasName~` = ` ~ Name ~ `;`); static if ( (is(Replace == class) || is(Replace == struct)) ) mixin(`alias `~aliasName~` = ` ~ Replace.stringof ~ `;`); else static assert(0); } struct A {} struct B {} struct C {} mixin makeAlias!("coolStruct", "MyStruct", A); mixin makeAlias!("coolStruct1", "B", C); void doSomething(coolStruct cs) { static if (!is(typeof(cs) == A)) static assert(0); //.. do something with struct .. } void doSomething1(coolStruct1 cs) { static if (!is(typeof(cs) == B)) static assert(0); //.. do something with struct .. } signature.asc Description: PGP signature
Re: alias and mixin
On Mon, 01 Sep 2014 10:57:41 + evilrat via Digitalmars-d-learn wrote: here's some more ugly hackery for you: string makeAlias(string aliasName, string Name, alias Replace) () { static if ( __traits(compiles, (mixin(Name~`.sizeof`))) ) return `alias `~aliasName~` = ` ~ Name ~ `;`; static if ( (is(Replace == class) || is(Replace == struct)) ) return `alias `~aliasName~` = ` ~ Replace.stringof ~ `;`; assert(0); } struct A {} mixin(makeAlias!("coolStruct", "MyStruct", A)); or: mixin template makeAlias(string aliasName, string Name, alias Replace) { static if ( __traits(compiles, (mixin(Name~`.sizeof`))) ) mixin(`alias `~aliasName~` = ` ~ Name ~ `;`); static if ( (is(Replace == class) || is(Replace == struct)) ) mixin(`alias `~aliasName~` = ` ~ Replace.stringof ~ `;`); else static assert(0); } struct A {} mixin makeAlias!("coolStruct", "MyStruct", A); signature.asc Description: PGP signature
Re: A significant performance difference
On Mon, 1 Sep 2014 12:51:58 +0200 Daniel Kozak via Digitalmars-d-learn wrote: > The problem is with searching first element yes. AAs aren't very good in "give me some so-called 'first' element", especially current druntime AAs. i'm not sure it worth heavy-fixing though. i sped it up a little (see bugzilla), but it will remain painfully slow, alas. AAs just don't fit in such use cases. signature.asc Description: PGP signature
Re: alias and mixin
On Sunday, 31 August 2014 at 12:01:43 UTC, evilrat wrote: On Sunday, 31 August 2014 at 11:43:03 UTC, ketmar via Digitalmars-d-learn wrote: On Sun, 31 Aug 2014 11:26:47 + evilrat via Digitalmars-d-learn wrote: alias myint = mixin("int"); // <- basic type expected blah blah mixin("alias myint = "~"int"~";"); ? wow, it works. i don't even think inverting it O_o you saved my day, thanks. ugh... somewhat related to original problem, made simple template for quick check if type present or provide alternative. now that is something i am not understand. sorry for my stupidness :( --- code struct A {} alias coolStruct = typeByName!("MyStruct", A); // oops, looks like alias is set to template itself, though // code completion(mono-d) shows it is correctly aliased to A // // error: template instance is used as a type void doSomething(coolStruct cs) { .. do something with struct .. } --- template itself template typeByName(alias Name, Replace) { static if ( __traits(compiles, (mixin(Name~`.sizeof`))) ) mixin(`alias typeByName = ` ~ Name ~ `;`); else static if ( (is(Replace == class) || is(Replace == struct)) ) alias typeByName = Replace; }
Re: A significant performance difference
V Mon, 1 Sep 2014 12:38:52 +0300 ketmar via Digitalmars-d-learn napsáno: > On Mon, 01 Sep 2014 09:22:50 + > bearophile via Digitalmars-d-learn > wrote: > > > In theory the best solution is to improve the performance of the > > "byKey.front" and "byValue.front" idioms. > i found that slowdown is from _aaRange(), not from delegates. > the following code is slow even w/o delegate creation: > > import core.stdc.stdio; > > ref K firstKey(T : V[K], V, K)(T aa) @property > { > return *cast(K*)_aaRangeFrontKey(_aaRange(cast(void*)aa)); > } > > ref V firstVal(T : V[K], V, K)(T aa) @property > { > return *cast(V*)_aaRangeFrontValue(_aaRange(cast(void*)aa)); > } > > > int main() { > long[int] aa; > for (int i = 0; i < 5; i++) > aa[i] = i; > > long total = 0; > > while (aa.length) { > //int k = aa.byKey.front; > int k = aa.firstKey; > //long v = aa.byValue.front; > long v = aa.firstVal; > aa.remove(k); > total += k + v; > } > > printf("%lld\n", total); > return 0; > } > > > seems that we need two more hooks for AAs: `_aaFrontKey()` and > `_aaFrontValue()`. > > > x.pop() sounds nicer :-) > ah, sure. i'm not very good in inventing names. ;-) > Yep, I found out something similar. with this ugly code for (i = 0; i < W; ++i) { y = null; while (x.length) { foreach(lj, lp ; x) { j = lj; p = lp; x.remove(cast(int)j); break; } ... } The problem is with searching first element
Re: A significant performance difference
On Mon, 01 Sep 2014 09:16:04 + bearophile via Digitalmars-d-learn wrote: > https://issues.dlang.org/show_bug.cgi?id=13410 i added 'quick-hack-patch' to your report which halves execution time without significantly hurting performance in other AA uses. now there is no difference between `long v = aa.byValue.front;` and `long v = aa[k];`. yet aa.remove() still hurts badly, and i don't think that we can do any better with it. signature.asc Description: PGP signature
Re: A significant performance difference
On Mon, 1 Sep 2014 12:38:52 +0300 ketmar via Digitalmars-d-learn wrote: > i found that slowdown is from _aaRange() and i'm wrong again. adding `_aaFrontKey()` and `_aaFrontValue()` makes no difference at all. that's 'cause both hooks need to go thru bucket array to find first entry. unless we add some ponter to 'first used bucket', getting 'first' key and value will be slow. so, to make this fast, we need to cache info about 'first used bucket'. i hacked in VERY simple caching, and... voila: execution time for 'byKey/byValue' variant drops from 3 seconds to 1.5 seconds. seems that it's as far as i can get without hurting AA performance in other cases. signature.asc Description: PGP signature
Re: How to compare two types?
Thanks for the answers!
Re: A significant performance difference
On Mon, 01 Sep 2014 09:22:50 + bearophile via Digitalmars-d-learn wrote: > In theory the best solution is to improve the performance of the > "byKey.front" and "byValue.front" idioms. i found that slowdown is from _aaRange(), not from delegates. the following code is slow even w/o delegate creation: import core.stdc.stdio; ref K firstKey(T : V[K], V, K)(T aa) @property { return *cast(K*)_aaRangeFrontKey(_aaRange(cast(void*)aa)); } ref V firstVal(T : V[K], V, K)(T aa) @property { return *cast(V*)_aaRangeFrontValue(_aaRange(cast(void*)aa)); } int main() { long[int] aa; for (int i = 0; i < 5; i++) aa[i] = i; long total = 0; while (aa.length) { //int k = aa.byKey.front; int k = aa.firstKey; //long v = aa.byValue.front; long v = aa.firstVal; aa.remove(k); total += k + v; } printf("%lld\n", total); return 0; } seems that we need two more hooks for AAs: `_aaFrontKey()` and `_aaFrontValue()`. > x.pop() sounds nicer :-) ah, sure. i'm not very good in inventing names. ;-) signature.asc Description: PGP signature
Re: A significant performance difference
ketmar: But I think the "j = x.byKey.front; p = x.byValue.front;" code looks sufficiently idiomatic, and its performance is terrible. that's why i suggest to extend AA API, adding x.firstKey and x.firstValue functions. i'll try to make the patch soon. In theory the best solution is to improve the performance of the "byKey.front" and "byValue.front" idioms. If that's not possible and you need to add the firstKey/firstValue functions, then it's a good idea to make the D front-end rewrite "byKey.front" with a call to "firstKey" and a "byValue.front" with a call to firstValue. ah, and x.getAndRemove() too, it's handy sometimes. but this will need new druntime hook, i think. ;-) x.pop() sounds nicer :-) Bye, bearophile
Re: A significant performance difference
It seems fit for a performance bug report. I have to create a synthetic benchmark that shows just the problem. https://issues.dlang.org/show_bug.cgi?id=13410 (Perhaps I have credited the wrong person there, sorry, I will fix). Bye, bearophile
Re: A significant performance difference
On Mon, 01 Sep 2014 08:53:45 + bearophile via Digitalmars-d-learn wrote: > This is a little cleaner: yes, i just did a 'quickhack' without even analyzing what the code does. ;-) signature.asc Description: PGP signature
Re: A significant performance difference
On Mon, 01 Sep 2014 08:53:45 + bearophile via Digitalmars-d-learn wrote: > ketmar: > Thank you for your analysis and code. actually, it's based on Daniel Kozak's observation, so credit him instead. ;-) > But I think the "j = x.byKey.front; p = x.byValue.front;" code > looks sufficiently idiomatic, and its performance is terrible. that's why i suggest to extend AA API, adding x.firstKey and x.firstValue functions. i'll try to make the patch soon. ah, and x.getAndRemove() too, it's handy sometimes. but this will need new druntime hook, i think. ;-) signature.asc Description: PGP signature
Re: A significant performance difference
ketmar: Thank you for your analysis and code. while (x.length) { foreach (key; x.keys) { auto pp = key in x; if (pp is null) continue; j = key; p = *pp; x.remove(j); This is a little cleaner: while (x.length) { foreach (immutable j; x.keys) { p = x[j]; x.remove(j); so yes, creating delegates are SLOW. even taking into account that we creating dynamic arrays with keys in this version, it's rockin' fast. This D version is much faster, it runs in about 0.26 seconds (while the C++ version runs in about 0.21 seconds), this is acceptable because x.keys allocates a dynamic array of keys in the middle of the code. But I think the "j = x.byKey.front; p = x.byValue.front;" code looks sufficiently idiomatic, and its performance is terrible. It seems fit for a performance bug report. I have to create a synthetic benchmark that shows just the problem. Bye, bearophile
Re: A significant performance difference
On Mon, 1 Sep 2014 09:21:03 +0200 Daniel Kozak via Digitalmars-d-learn wrote: and this version executes in 0.2 seconds: import core.stdc.stdio; immutable H = 9, W = 12; immutable uint[3][6] g = [ [7, 0, H - 3], [1 + (1 << H) + (1 << (2 * H)), 0, H - 1], [3 + (1 << H), 0, H - 2], [3 + (2 << H), 0, H - 2], [1 + (1 << H) + (2 << H), 0, H - 2], [1 + (1 << H) + (1 << (H - 1)), 1, H - 1] ]; int main () { ulong p, i, k; uint j, l; ulong[uint] x, y; x[0] = 1; for (i = 0; i < W; ++i) { y = null; while (x.length) { foreach (key; x.keys) { auto pp = key in x; if (pp is null) continue; j = key; p = *pp; x.remove(j); for (k = 0; k < H; ++k) { if ((j & (1 << k)) == 0) break; } if (k == H) { y[j >> H] += p; } else { for (l = 0; l < 6; ++l) { if (k >= g[l][1] && k <= g[l][2]) { if ((j & (g[l][0] << k)) == 0) { x[j + (g[l][0] << k)] += p; } } } } } } x = y; } printf("%lld\n", y[0]); return 0; } so yes, creating delegates are SLOW. even taking into account that we creating dynamic arrays with keys in this version, it's rockin' fast. signature.asc Description: PGP signature
Re: A significant performance difference
On Mon, 1 Sep 2014 09:21:03 +0200 Daniel Kozak via Digitalmars-d-learn wrote: > I think main problem is in calling delegates (x.byKey.front and > x.byValue.front;). If I change x.byValue.front with x[j], It makes > program a lot faster yes. replacing `p = x.byValue.front;` by `p = x[j];` cutted down execution time from 3.2 seconds to 1.8 seconds with my gdc. i always dreamt about official 'get any key from AA' API. and, btw, 'get value and remove key' API too. they are useful sometimes. seems that i have to write another silly patch for this. ;-) signature.asc Description: PGP signature
Re: Possible difference in compilers?
Charles: My solution I came up with (and works locally) is: import std.stdio; void main() { int height=1,t=1,oldN=0,n; readf(" %d\n", &t); foreach (i;0 .. t) { readf(" %d\n", &n); foreach (j; oldN .. n) I suggest to add a blank line after the import, to move the import inside the main, to add a space after the commas, and to add an immutable to foreach variable. Bye, bearophile
Re: A significant performance difference
V Sun, 31 Aug 2014 10:55:31 + bearophile via Digitalmars-d-learn napsáno: > This is C++ code that solves one Euler problem: > > -- > #include > #include > > const unsigned int H = 9, W = 12; > > const int g[6][3] = {{7, 0, H - 3}, > {1 + (1 << H) + (1 << (2 * H)), 0, H - 1}, > {3 + (1 << H), 0, H - 2}, > {3 + (2 << H), 0, H - 2}, > {1 + (1 << H) + (2 << H), 0, H - 2}, > {1 + (1 << H) + (1 << (H - 1)), 1, H - 1}}; > > int main() { > unsigned long long p, i, k; > unsigned int j, l; > std::map x, y; > x[0] = 1; > > for (i = 0; i < W; ++i) { > y.clear(); > while (!x.empty()) { > j = x.begin()->first; > p = x.begin()->second; > x.erase(x.begin()); > > for (k = 0; k < H; ++k) > if ((j & (1 << k)) == 0) > break; > > if (k == H) > y[j >> H] += p; > else > for (l = 0; l < 6; ++l) > if (k >= g[l][1] && k <= g[l][2]) > if ((j & (g[l][0] << k)) == 0) > x[j + (g[l][0] << k)] += p; > } > x = y; > } > > printf("%lld\n", y[0]); > return 0; > } > -- > > > I have translated it to D like this (I know in D there are nicer > ways to write it, but I have tried to keep the look of the code > as much similar as possible to the C++ code): > > > -- > import core.stdc.stdio; > > const uint H = 9, W = 12; > > const uint[3][6] g = [[7, 0, H - 3], >[1 + (1 << H) + (1 << (2 * H)), 0, H - 1], >[3 + (1 << H), 0, H - 2], >[3 + (2 << H), 0, H - 2], >[1 + (1 << H) + (2 << H), 0, H - 2], >[1 + (1 << H) + (1 << (H - 1)), 1, H - 1]]; > > int main() { > ulong p, i, k; > uint j, l; > ulong[uint] x, y; > x[0] = 1; > > for (i = 0; i < W; ++i) { > y = null; > while (x.length) { > j = x.byKey.front; > p = x.byValue.front; > x.remove(cast(int)j); > > for (k = 0; k < H; ++k) > if ((j & (1 << k)) == 0) > break; > > if (k == H) > y[j >> H] += p; > else > for (l = 0; l < 6; ++l) > if (k >= g[l][1] && k <= g[l][2]) > if ((j & (g[l][0] << k)) == 0) > x[j + (g[l][0] << k)] += p; > } > x = y; > } > > printf("%lld\n", y[0]); > return 0; > } > -- > > > The C++ code is much faster than the D code (I see the D code 30+ > times slower with dmd and about like 20 times with ldc2). One > difference between the C++ and D code is that the C++ map uses a > search tree (red-black probably), while the D code uses a hash. > > To test that algorithmic difference, if I replace the map in the > C++ code with a std::unordered_map (C++11): > > #include > ... > std::unordered_map x, y; > > > then the run-time increases (more than two times) but it's still > much faster than the D code. > > Is it possible to fix the D code to increase its performance > (there are associative array libraries for D, but I have not > tried them in this program). > > Bye, > bearophile I think main problem is in calling delegates (x.byKey.front and x.byValue.front;). If I change x.byValue.front with x[j], It makes program a lot faster