Re: How to use D without the GC ?
On Wednesday, 12 June 2024 at 21:59:54 UTC, drug007 wrote: Yes, but you get all the benefits of `double[]` for free if you do it that way, including the more concise foo[10] syntax. I meant you do not need to add `ptr` field at all I see. You're right. I thought it would be easier for someone new to the language to read more explicit code rather than assuming knowledge about data.ptr. In practice it's better to not have a ptr field.
Re: How to use D without the GC ?
On Wednesday, 12 June 2024 at 21:36:30 UTC, Dukc wrote: bachmeier kirjoitti 12.6.2024 klo 18.21: You're splitting things into GC-allocated memory and manually managed memory. There's also SafeRefCounted, which handles the malloc and free for you. I suspect `SafeRefCounted` (or `RefCounted`) is not the best fit for this scenario. The problem with it is it `malloc`s and `free`s individual objects, which doesn't sound efficient to me. Maybe it performs if the objects in question are big enough, or if they can be bundled to static arrays so there's no need to refcount individual objects. But even then, you can't just allocate and free dozens or hundreds of megabytes with one call, unlike with the GC or manual `malloc`/`free`. I honestly don't know if calling malloc/free for, say each 64KiB, would have performance implications over a single allocation. Why would it be different from calling malloc and free manually? I guess I'm not understanding, because you put the same calls to malloc and free that you'd otherwise be doing inside this and ~this.
Re: How to load a DLL file in D?
On Saturday, 11 May 2024 at 20:04:38 UTC, Lance Bachmeier wrote: On Saturday, 11 May 2024 at 19:33:03 UTC, solidstate1991 wrote: I know that BindBC exists and otherwise would use it, but the bigger the library, the more extra hurdle it'll have. When I did a few bindings with it, I had to order the functions the right way, so I could do things much quicker with the Ctrl+Alt+Shift trick under VSCode, and even then having to write both a statically linked and dynamically linked version (the latter which required the functions to be loaded individually into function pointers). Maybe I should write some automation tool... You might find this package useful https://code.dlang.org/packages/dynamic Also relevant if they're C functions: https://forum.dlang.org/post/qxctappnigkwvaqak...@forum.dlang.org And this if you want to convert C headers to D code: https://forum.dlang.org/post/ugvc3o$5t3$1...@digitalmars.com
Re: How to load a DLL file in D?
On Saturday, 11 May 2024 at 19:33:03 UTC, solidstate1991 wrote: I know that BindBC exists and otherwise would use it, but the bigger the library, the more extra hurdle it'll have. When I did a few bindings with it, I had to order the functions the right way, so I could do things much quicker with the Ctrl+Alt+Shift trick under VSCode, and even then having to write both a statically linked and dynamically linked version (the latter which required the functions to be loaded individually into function pointers). Maybe I should write some automation tool... You might find this package useful https://code.dlang.org/packages/dynamic
Re: Phobos function to remove all occurances from dynamic array?
On Wednesday, 1 May 2024 at 15:18:03 UTC, Steven Schveighoffer wrote: On Wednesday, 1 May 2024 at 01:09:33 UTC, Liam McGillivray wrote: This is presumably such a common task that I'm surprised it isn't easy to find the answer by searching; Is there a standard library function that removes all elements from a dynamic array that matches an input argument? In `std.array` there's the `replace` function which is supposed to replace all occurrences that match an input with another. It seems to work as described on strings, but I get compiler errors when using it on other array types. I've tried using it to replace occurrences of a certain object in an array with `[]` in order to remove all occurrences, but it's not allowed. Is there a Phobos function that does what I want? It would be crazy if there isn't. `remove` https://dlang.org/phobos/std_algorithm_mutation.html#remove ```d arr = arr.remove!(v => shouldBeRemoved(v)); ``` Why the reassignment? Because `remove` removes elements *in place*, and does not change the range extents. It returns the portion of the range that contains the unremoved elements. So to give an example: ```d auto arr = [1, 2, 3, 4, 5]; auto result = arr.remove!(i => i % 2 == 1); // remove odd elements assert(result == [2, 4]); // first 2 are the slice that is stored in result // the last three are leftovers. assert(arr == [2, 4, 3, 4, 5]); ``` -Steve In case anyone comes upon this in a search, I wanted to point out a couple dangers of using remove. The first is that it mutates arr, as shown in Steve's example. The second is ``` result[0] = 4; assert(result == [4, 4]); assert(arr == [2, 4, 3, 4, 5]); // Fails arr[0] = 2; assert(result == [4, 4]); // Fails ``` Any future changes you make to result or arr change the other. You can use remove to avoid the allocation of a new array, but you better be sure you never read or modify the original array again. If you use filter ``` auto result = arr.filter!(i => i % 2 == 0).array; ``` arr is unchanged and you can use arr and result as you want.
Re: Phobos function to remove all occurances from dynamic array?
On Wednesday, 1 May 2024 at 01:09:33 UTC, Liam McGillivray wrote: This is presumably such a common task that I'm surprised it isn't easy to find the answer by searching; Is there a standard library function that removes all elements from a dynamic array that matches an input argument? In `std.array` there's the `replace` function which is supposed to replace all occurrences that match an input with another. It seems to work as described on strings, but I get compiler errors when using it on other array types. I've tried using it to replace occurrences of a certain object in an array with `[]` in order to remove all occurrences, but it's not allowed. Is there a Phobos function that does what I want? It would be crazy if there isn't. Does filter do what you need? https://dlang.org/phobos/std_algorithm_iteration.html#.filter
Re: Recommendations on porting Python to D
On Wednesday, 24 April 2024 at 19:50:45 UTC, Chris Piker wrote: is anyone aware of any tools that generate an abstract syntax tree which could then be converted to somewhat equivalent D code? This might give me a jump-start on the manual conversion process. Then later I can work on removing the CGI dependency. I haven't used Python much in recent years, but my recollection is that Python 2 had an ast module that would spit out the ast for you.
Re: Best way to use large C library in D as of 2024
On Friday, 12 April 2024 at 18:36:13 UTC, Chris Piker wrote: On Saturday, 30 March 2024 at 07:11:49 UTC, Mike Parker wrote: Though I appreciate the sentiment, it's much more effective and efficient for people actually using the feature, and who appreciate it, to write up a blog post about it somewhere and share that on Twitter/Reddit/HN, etc. I would, but I'm just not a social media person. I pretty much only post online content here and at github.com. You may have the problem that D doesn't attract "very-online" personality types. I do mention D in work presentations, but those are not visible to the public. If you put your writeup in a markdown file on your Github account and then post a link in the announce group, others will post it to the D subreddit and elsewhere I'm sure.
Re: Best way to use large C library in D as of 2024
On Friday, 12 April 2024 at 18:45:21 UTC, Chris Piker wrote: Even though DMD can't compile some C code, that's pretty much a non-issue for me anyway. In my environment the servers are all Linux so "apt-get" (or equivalent) typically provides a pre-compiled dependency. Being able to list a package as a system dependency and then just call it from D with no interface code is a Big Freaking Deal! Compared to Python interfaces this is a huge improvement. It makes D an even better replacement for the mixed mode python + C development I was doing before switching to D for new projects. I agree that it's really good, but the issues I listed were just examples of the things I came across, and I know there are a decent number of other open issues for ImportC. What I'd prefer to avoid is having people try it out and concluding that it's not ready. Kind of like when I tried out Zig. Everyone was saying it's this great language but my trial was brief and I haven't been tempted to try it since. Header files are a different story. They really should "just work" based on my experience. Other things like compiling large libraries or translating C code to D should probably be more in the camp of "experience reports" posted on individual blogs, and they should talk about both the successes and the edge cases.
Re: Unittests pass, and then an invalid memory operation happens after?
On Wednesday, 3 April 2024 at 21:57:00 UTC, Liam McGillivray wrote: Alright. I suppose that some of the optimization decisions I have made so far may have resulted in less readable code for little performance benefit. Now I'm trying to worry less about optimization. Everything has been very fast so far. I haven't used a profiler yet, but I may like to try it. A good example where you people will get fooled is to avoid passing structs as function arguments/return values because you're worried about copying: https://forum.dlang.org/post/jifumskhdmxkimtay...@forum.dlang.org I'm guilty of having done that regularly until I learned how the compiler actually works and how little time certain operations take. One time I even changed clear string arguments to hard-to-remember single char values inside a loop.
Re: Best way to use large C library in D as of 2024
On Saturday, 30 March 2024 at 05:01:32 UTC, harakim wrote: On Tuesday, 26 March 2024 at 20:42:00 UTC, Chris Piker wrote: On Tuesday, 26 March 2024 at 20:19:27 UTC, bachmeier wrote: Should be able to just use it, as described here: https://forum.dlang.org/post/qxctappnigkwvaqak...@forum.dlang.org Create a .c file that includes the header files and then call the functions you need. Wow. **That just worked the first time!** Holy &^@$ that's easy! So why does the 2nd page returned from the google search ``` interfacing with C site:dlang.org ``` (which happens to be: https://dlang.org/spec/interfaceToC.html) still have this text: Since D can call C code directly, it can also call any C library functions, giving D access to the smorgasbord of existing C libraries. To do so, however, one needs to write a D interface (.di) file, which is a translation of the C .h header file for the C library into D. For popular C libraries, the first place to look for the corresponding D interface file is the Deimos Project. If it isn't there already, please write and contribute one to the Deimos Project. ? This lead me to believe that interfacing was a chore and I was considering going back to C for a small program I need. @D Language Foundation - This is a HUGE selling point. I had to use cups the other day and I just copied some code from a d file and linked the library. It was so easy I was suspicious but it worked. Using C from D is pretty much as easy as using C from C and I think you should advertise that better! It works well if you only need to work with a header. There are still a few rough edges that get in the way if you're compiling the full C sources (I filed bugs for all of them): - Can't handle va_arg - Can't cast to a pointer of a struct that's typedef'd - Can't use complex numbers with the ternary operator These problems should be cleaned up before heavily promoting what is an incredible feature. I don't think it's widely known that you can translate C source files into D. I think that's really cool, but in addition to the bugs listed above that ImportC can't handle, it outputs things like dpulicate aliases, function argument names that are D keywords, and declaring unions inside structs equal to void. All of these are easy to fix by hand, but it's time consuming. Once these final odds and ends are working, we have a killer language feature.
Re: Why is this code slow?
On Tuesday, 26 March 2024 at 14:25:53 UTC, Lance Bachmeier wrote: On Sunday, 24 March 2024 at 19:31:19 UTC, Csaba wrote: I know that benchmarks are always controversial and depend on a lot of factors. So far, I read that D performs very well in benchmarks, as well, if not better, as C. I wrote a little program that approximates PI using the Leibniz formula. I implemented the same thing in C, D and Python, all of them execute 1,000,000 iterations 20 times and display the average time elapsed. Here are the results: C: 0.04s Python: 0.33s D: 0.73s What the hell? D slower than Python? This cannot be real. I am sure I am making a mistake here. I'm sharing all 3 programs here: C: https://pastebin.com/s7e2HFyL D: https://pastebin.com/fuURdupc Python: https://pastebin.com/zcXAkSEf As you can see the function that does the job is exactly the same in C and D. Here are the compile/run commands used: C: `gcc leibniz.c -lm -oleibc` D: `gdc leibniz.d -frelease -oleibd` Python: `python3 leibniz.py` PS. my CPU is AMD A8-5500B and my OS is Ubuntu Linux, if that matters. As others suggested, pow is the problem. I noticed that the C versions are often much faster than their D counterparts. (And I don't view that as a problem, since both are built into the language - my only thought is that the D version should call the C version). Changing ``` import std.math:pow; ``` to ``` import core.stdc.math: pow; ``` and leaving everything unchanged, I get C: Avg execution time: 0.007918 D (original): Avg execution time: 0.102612 D (using core.stdc.math): Avg execution time: 0.008134 So more or less the exact same numbers if you use core.stdc.math. And then the other thing is changing ``` const int BENCHMARKS = 20; ``` to ``` enum BENCHMARKS = 20; ``` which should allow substitution of the constant directly into the rest of the program, which gives ``` Avg execution time: 0.007564 ``` On my Ubuntu 22.04 machine, therefore, the LDC binary with no flags is slightly faster than the C code compiled with your flags.
Re: Why is this code slow?
On Sunday, 24 March 2024 at 19:31:19 UTC, Csaba wrote: I know that benchmarks are always controversial and depend on a lot of factors. So far, I read that D performs very well in benchmarks, as well, if not better, as C. I wrote a little program that approximates PI using the Leibniz formula. I implemented the same thing in C, D and Python, all of them execute 1,000,000 iterations 20 times and display the average time elapsed. Here are the results: C: 0.04s Python: 0.33s D: 0.73s What the hell? D slower than Python? This cannot be real. I am sure I am making a mistake here. I'm sharing all 3 programs here: C: https://pastebin.com/s7e2HFyL D: https://pastebin.com/fuURdupc Python: https://pastebin.com/zcXAkSEf As you can see the function that does the job is exactly the same in C and D. Here are the compile/run commands used: C: `gcc leibniz.c -lm -oleibc` D: `gdc leibniz.d -frelease -oleibd` Python: `python3 leibniz.py` PS. my CPU is AMD A8-5500B and my OS is Ubuntu Linux, if that matters. As others suggested, pow is the problem. I noticed that the C versions are often much faster than their D counterparts. (And I don't view that as a problem, since both are built into the language - my only thought is that the D version should call the C version). Changing ``` import std.math:pow; ``` to ``` import core.stdc.math: pow; ``` and leaving everything unchanged, I get C: Avg execution time: 0.007918 D (original): Avg execution time: 0.102612 D (using core.stdc.math): Avg execution time: 0.008134 So more or less the exact same numbers if you use core.stdc.math.
Re: The difference between the dates in years
On Saturday, 10 February 2024 at 21:56:30 UTC, Lance Bachmeier wrote: On Saturday, 10 February 2024 at 15:53:09 UTC, Alexander Zhirov wrote: Is it possible to calculate the difference between dates in years using regular means? Something like that ``` writeln(Date(1999, 3, 1).diffMonths(Date(1999, 1, 1))); ``` At the same time, keep in mind that the month and day matter, because the difference between the year, taking into account the month that has not come, will be less. My abilities are not yet enough to figure it out more elegantly. I'm assuming you mean you want the number of full years between the dates. If so, I use something like this: ``` import std; void main() { writeln(fullYears(Date(1999, 3, 1), Date(1999, 2, 1))); writeln(fullYears(Date(2000, 3, 1), Date(1999, 2, 1))); writeln(fullYears(Date(2000, 3, 1), Date(1999, 4, 1))); writeln(fullYears(Date(2006, 4, 1), Date(1999, 4, 1))); } bool earlierInYear(Date date1, Date date2) { return date1 < Date(date1.year, date2.month, date2.day); } long fullYears(Date date1, Date date2) { assert(date1 >= date2, "The first date has to be later"); if (date1.earlierInYear(date2)) { return max(date1.year - date2.year, 0); } else { return date1.year - date2.year; } } ``` should be ``` long fullYears(Date date1, Date date2) { assert(date1 >= date2, "The first date has to be later"); if (date1.earlierInYear(date2)) { return max(date1.year - date2.year - 1, 0); } else { return date1.year - date2.year; } } ```
Re: The difference between the dates in years
On Saturday, 10 February 2024 at 15:53:09 UTC, Alexander Zhirov wrote: Is it possible to calculate the difference between dates in years using regular means? Something like that ``` writeln(Date(1999, 3, 1).diffMonths(Date(1999, 1, 1))); ``` At the same time, keep in mind that the month and day matter, because the difference between the year, taking into account the month that has not come, will be less. My abilities are not yet enough to figure it out more elegantly. I'm assuming you mean you want the number of full years between the dates. If so, I use something like this: ``` import std; void main() { writeln(fullYears(Date(1999, 3, 1), Date(1999, 2, 1))); writeln(fullYears(Date(2000, 3, 1), Date(1999, 2, 1))); writeln(fullYears(Date(2000, 3, 1), Date(1999, 4, 1))); writeln(fullYears(Date(2006, 4, 1), Date(1999, 4, 1))); } bool earlierInYear(Date date1, Date date2) { return date1 < Date(date1.year, date2.month, date2.day); } long fullYears(Date date1, Date date2) { assert(date1 >= date2, "The first date has to be later"); if (date1.earlierInYear(date2)) { return max(date1.year - date2.year, 0); } else { return date1.year - date2.year; } } ```
Re: Using C header libs with importC
On Monday, 8 January 2024 at 18:53:47 UTC, Renato wrote: Is it possible to use C header-only libs from D? In C, I would need to do this: ```c #define STB_DS_IMPLEMENTATION #include "stb_ds.h" ``` The definition must be done in a single C file before including the h file. I tried this in D: ```d enum STB_DS_IMPLEMENTATION = 1; import stb_ds; ``` But it doesn't work. Any suggestions? Perhaps using an intermediate C file to do this would work, but I wanted to know if D can do it. Without knowing the specifics of what you're trying to do, this automatic translation of C headers to D might be what you want: https://forum.dlang.org/post/ugvc3o$5t3$1...@digitalmars.com The way "header-only" is usually used suggests you should change the file extension to .c and compile it directly.