Re: Find in assoc array then iterate
Hi Sergey, While the unordered map doesn't guarantee an ordering (since its contents are hashed), the order should remain static if you don't insert or delete. Hi JG, Thanks for the red-black tree reference. I'll read up on it in case I need it but I'd prefer to use the built-in O(1) hash map. Hi again Ali!, I did consider a sort, but it has a number of downsides: - it's O(n ln(n)) - if I'm understanding correctly, it would require additional memory - Not relevant to my problem but, if you had duplicates, it wouldn't handle stopping in the middle of some duplicates and re-starting; only iterators support this. One could more easily copy the keys into an array, and iterate on them. Thus, I was hoping to find a member function that would support this. Steven, Just because you don't see the value doesn't mean I don't. You should try to be more helpful, or don't bother.
Re: Find in assoc array then iterate
On 10/21/22 6:03 PM, Kevin Bailey wrote: I'm trying to do this equivalent C++: unordered_map map; for (auto i = map.find(something); i != map.end(); ++i) ...do something with i... in D, but obviously with an associative array. It seems that it's quite easy to iterate through the whole "map", but not start from the middle. Am I missing something obvious (or not so obvious) ? What you are missing is that it's something that provides almost no value. A question to answer is *why* you want to iterate an "unordered" map from the middle? -Steve
Re: Find in assoc array then iterate
On 10/21/22 15:03, Kevin Bailey wrote: I'm trying to do this equivalent C++: unordered_map map; for (auto i = map.find(something); i != map.end(); ++i) ...do something with i... in D, but obviously with an associative array. It seems that it's quite easy to iterate through the whole "map", but not start from the middle. Am I missing something obvious (or not so obvious) ? Something like the following perhaps, which sorts the keys: import std; // Sorry :( void main() { auto m = iota(20).map!(i => tuple(i, format!"value_%s"(i))).assocArray; foreach (key; m.keys.sort.find(13)) { writeln(m[key]); } } Ali
Re: Find in assoc array then iterate
On Friday, 21 October 2022 at 22:03:53 UTC, Kevin Bailey wrote: I'm trying to do this equivalent C++: unordered_map map; for (auto i = map.find(something); i != map.end(); ++i) ...do something with i... in D, but obviously with an associative array. It seems that it's quite easy to iterate through the whole "map", but not start from the middle. Am I missing something obvious (or not so obvious) ? You can build a map using a red black tree. Then you should be able to do what you want. https://dlang.org/phobos/std_container_rbtree.html
Re: Find in assoc array then iterate
On Friday, 21 October 2022 at 22:03:53 UTC, Kevin Bailey wrote: I'm trying to do this equivalent C++: unordered_map map; for (auto i = map.find(something); i != map.end(); ++i) ...do something with i... in D, but obviously with an associative array. It seems that it's quite easy to iterate through the whole "map", but not start from the middle. Am I missing something obvious (or not so obvious) ? How should that work, if map is unordered? In D: Implementation Defined: The built-in associative arrays do not preserve the order of the keys inserted into the array. In particular, in a foreach loop the order in which the elements are iterated is typically unspecified. https://dlang.org/spec/hash-map.html
Find in assoc array then iterate
I'm trying to do this equivalent C++: unordered_map map; for (auto i = map.find(something); i != map.end(); ++i) ...do something with i... in D, but obviously with an associative array. It seems that it's quite easy to iterate through the whole "map", but not start from the middle. Am I missing something obvious (or not so obvious) ?
Re: [Help Needed] - Debugging compilation time
On Friday, 21 October 2022 at 16:32:17 UTC, Hipreme wrote: Hey guys, I have been complaining a lot of time right now from D compilation speed at least for my project. I have: - Underused CTFE - Underused Templates - Avoided importing standard libraries - Created a multi module projects for better code reuse The slow is from executing CTFE (template constraints, enum expression, static if ...). The culprit is this function: Expression.ctfeInterpret() in this module dmd.expression.d Even for compiling DMD, that function will take 1/3 of total times Try to reduce CTFE usage than it will be fast again. D should analyze to make executing CTFE faster Cheers
Re: [Help Needed] - Debugging compilation time
Make sure you have the latest version of DMD Make sure your antivirus isn't blocking your files (scanning), it's a common thing with Windows, whitelist dmd folder, your dev folder and dub folder
Re: [Help Needed] - Debugging compilation time
I tried your project: Linux x64 ``` git clone https://github.com/MrcSnm/HipremeEngine.git cd HipremeEngine dub build (once to download dependencies if any) time dub build -f real0m4.604s user0m3.686s sys 0m0.900s ``` 4.6 sec for a FULL rebuild doesn't seem that bad and ``` real0m1.730s user0m1.480s sys 0m0.245s ``` after editing one module, not bad at all As other people say: LDC for release with optimizations DMD for development THat's what i personally do
Re: DConf '22: No-Allocated 0-terminated path strings
On Friday, 21 October 2022 at 14:34:47 UTC, ag0aep6g wrote: Nitpick: You cannot iterate a true input range twice. You need a forward range for that. Nitpick²: you don't actually need to iterate the range twice ```d //version=AllowMalloc; auto toCStringThen(alias dg, Range)(Range src) /*nothrow*/ if (isInputRange!Range && !isInfinite!Range) { char[10] small = void; size_t i = 0; while(!src.empty && i < small.length) { small[i++] = src.front; src.popFront; } if(i == small.length) { version(AllowMalloc) { import std.container.array; Array!char large = small[]; large ~= src; large ~= '\0'; return dg(large.data); } else { throw new Exception( "C string buffer overflow (%s >= %s)" .format(i+src.walkLength, small.length-1) ); } } else { small[i] = '\0'; return dg(small[0..i]); } } ``` Unfortunately this version does multiple allocations if contents of the range do not fit into the small buffer, but you could avoid that by detecting if `src` is a forward range/defines `.length` and doing `large.reserve` or something similar.
Re: [Help Needed] - Debugging compilation time
On Fri, Oct 21, 2022 at 04:32:17PM +, Hipreme via Digitalmars-d-learn wrote: > Hey guys, I have been complaining a lot of time right now from D > compilation speed at least for my project. > > I have: > - Underused CTFE > - Underused Templates > - Avoided importing standard libraries > - Created a multi module projects for better code reuse > > Those are all the techniques I have tried to maintain my compilation > times lower, yet, It still builds slow even when using the --combined > (which does a single compiler run on dub) Using dub immediately slows you down by at least several seconds. There may be some options to skip the time-consuming dependency graph resolution and network access. But my personal preference is to use an offline build system with less overhead. > So, doesn't matter if all is imported at once or not, it seems the > problem seems to be somewhere in my project which I've been unable to > find. I wanted to show someone who is more experienced on the time > trace from LDC to check what I've been doing wrong. LDC generally tends to be quite a bit slower than DMD because of the time spent in aggressive optimizations. For development builds, consider using DMD instead. > This time trace took 9 seconds. DMD takes 7 seconds to build my > project. Adam has built his entire arsd in 2.5 seconds, while my PC > is faster and arsd is much bigger than my project, this does not make > any sense. It could be caused by a number of different things: - Using many nested templates will slow down compilation. - Doing excessive CTFE computations will slow things down. - Using unusually-large static arrays in some cases may trigger slow paths in the front-end, consuming lots of compiler memory. - Using string imports may slow things down as the compiler parses the imported file(s). - Having excessively-large function bodies may trigger some O(n^2) paths in the compiler that significantly slows things down. - Using excessive mixins may also slow things down due to copying of the AST. OTOH, uninstantiated templates are cheap (the only cost is parsing them, which is very fast): just avoiding templates along may not save you much time if it's being spent elsewhere. I suspect a good chunk of Adam's code is in uninstantiated templates, so a straight comparison isn't really fair, if those templates aren't actually being instantiated in the first place. I also notice you use mixin templates a lot; it might be worth investigating whether they might be the cause of your issue. > So I would gladly wish you guys help: > > My repository: https://github.com/MrcSnm/HipremeEngine/ > My time trace: https://ufile.io/gmvw1wlu (This time trace will be in air for > 30 days only) Sorry, no time to look into it in detail, but I did skim over a few files and note that you use mixin templates a lot. I haven't had much experience with mixin templates but it might be worth investigating whether they might be causing compile time slowdowns. T -- They say that "guns don't kill people, people kill people." Well I think the gun helps. If you just stood there and yelled BANG, I don't think you'd kill too many people. -- Eddie Izzard, Dressed to Kill
[Help Needed] - Debugging compilation time
Hey guys, I have been complaining a lot of time right now from D compilation speed at least for my project. I have: - Underused CTFE - Underused Templates - Avoided importing standard libraries - Created a multi module projects for better code reuse Those are all the techniques I have tried to maintain my compilation times lower, yet, It still builds slow even when using the --combined (which does a single compiler run on dub) So, doesn't matter if all is imported at once or not, it seems the problem seems to be somewhere in my project which I've been unable to find. I wanted to show someone who is more experienced on the time trace from LDC to check what I've been doing wrong. This time trace took 9 seconds. DMD takes 7 seconds to build my project. Adam has built his entire arsd in 2.5 seconds, while my PC is faster and arsd is much bigger than my project, this does not make any sense. So I would gladly wish you guys help: My repository: https://github.com/MrcSnm/HipremeEngine/ My time trace: https://ufile.io/gmvw1wlu (This time trace will be in air for 30 days only)
Re: DConf '22: No-Allocated 0-terminated path strings
On Friday, 21 October 2022 at 13:49:01 UTC, cc wrote: ```d //version=AllowMalloc; auto toCStringThen(alias dg, Range)(Range src) /*nothrow*/ if (isInputRange!Range && !isInfinite!Range) { ``` [...] May need to be cleaned up for character types and needs to iterate twice if allocations are going to be allowed Nitpick: You cannot iterate a true input range twice. You need a forward range for that.
DConf '22: No-Allocated 0-terminated path strings
Catching up on the DConf '22 videos, really enjoyed the tricks Walter presents here for no-allocation strings: [DConf '22: Strawberries and Cream aka Delightful Emergent Properties of D -- Walter Bright](https://www.youtube.com/watch?v=iuP-AWUyjp8) In the Q segment, the first question asked whether the filename in the path example needs memory allocation to be passed to C, and is told it does, however the two methods presented can be easily combined to provide no-allocation 0-terminated strings from `chain()`ed paths by passing an `InputRange` rather than a `const(char)` to `toCStringThen`: ```d //version=AllowMalloc; auto toCStringThen(alias dg, Range)(Range src) /*nothrow*/ if (isInputRange!Range && !isInfinite!Range) { const len = src.walkLength; char[512] small = void; version(AllowMalloc) { import dmd.common.string : SmallBuffer; auto sb = SmallBuffer!char(len + 1, small[]); scope ptr = sb[]; } else { enforce(len < small.length, format!"C string buffer overflow (%s >= %s)"(len, small.length)); scope ptr = small[]; } size_t i = 0; foreach (char c; src) ptr[i++] = c; ptr[len] = '\0'; return dg(ptr); } void main() { string path = "include/"; string name = "file"; string ext = ".ext"; auto filename = chain(path, name, ext); filename.writeln; filename.byChar.toCStringThen!( (str) => printf("printf: {%s}\n", str.ptr) ); } ``` May need to be cleaned up for character types and needs to iterate twice if allocations are going to be allowed, and walkLength/chain()'s range functions aren't nothrow as far as I can tell. But otherwise thought this was kind of neat, just posting it here in case anyone else finds it handy.
Re: How to pass noncopyable variadic arguments with ref?
On Thursday, 20 October 2022 at 14:03:10 UTC, tchaloupka wrote: Hi, I've found strange behavior where: ```D import std.stdio; struct Foo { @disable this(this); int x; } void test(Foo[] foos...) { foreach (ref f; foos) { writeln(, ": ", f.x); f.x = 0; } } void main() { Foo f1 = Foo(1); Foo f2 = Foo(2); writeln("f1: ", ); writeln("f2: ", ); test(f1, f2); writeln("f1: ", f1.x); writeln("f2: ", f2.x); } ``` Compiles fine (no error on passing noncopyable arguments to the function), but there are other objects passed to the function as they aren't cleared out in the caller scope. Shouldn't it at least protest that objects can't be passed to the function as they aren't copyable? void test(Foo..)(Foo foos) I don't know if that's the 1:1 alternative, but that doesn't compile onlineapp.d(23): Error: struct `onlineapp.Foo` is not copyable because it has a disabled postblit
Alpine: static compilation
Hi D-community. I try to build and run very simple code on Alpine docker image - but have no luck with static builds and LTO. The desired aim is to be able build it similar to C code compilation: ```c gcc leibniz.c -o leibniz -O3 -s -static -flto -march=native -mtune=native -fomit-frame-pointer -fno-signed-zeros -fno-trapping-math -fassociative-math ``` I'd like to find working examples for both LDC and GDC for static compilation. If you have one, share it here please. For LDC I've tried to install this packages: ``` RUN apk add --no-cache ldc gcc ldc-static binutils-gold ``` and build it with parameters: ``` cc=gcc ldc2 -O3 -release -mcpu=native -flto=full -linker=gold -flto-binary=/usr/bin/ld.gold -defaultlib=phobos2-ldc-lto,druntime-ldc-lto -m64 -static leibniz.d ``` Some issues that I've faced while trying different options: - 'cc=clang' suddenly is not working. It still saying "can't find cc" - Without explicit 'flto-binary=' the error was about "LLVMgold (plugin) not found". The code: ```d import std.stdio; import std.file; double pi = 1.0; uint rounds; void main() { auto file = File("./rounds.txt", "r"); file.readf!"%d\n"(rounds); rounds += 2u; foreach(i; 2u .. rounds) { double x = -1.0 + 2.0 * (i & 0x1); pi += (x / (2u * i - 1u)); } pi *= 4.0; writefln("%.16f", pi); } ```