Re: Best way to use large C library in D as of 2024
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. It's a recent thing that it works this well. Hopefully that page gets updated.
Re: Best way to use large C library in D as of 2024
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.
Re: Best way to use large C library in D as of 2024
On Tuesday, 26 March 2024 at 19:24:39 UTC, Chris Piker wrote: Hi D I have a C library I use for work, it's maintained by an external organization that puts it through a very through test framework. Though source code is supplied, the intended use is to include the header files and link against pre-compiled code. What is the best way, as of 2024 to use this library with D, in particular dmd? ImportC doesn't seem like the go-to option since the C source does not need to be complied. I've seen some forum post indicating that manually generated D wrappers are no longer needed, but I'm fuzzy on the particulars. If there's any blog posts or other instructions you'd like to reference I'd be happy to check them out. For reference here's the C library in question: https://naif.jpl.nasa.gov/naif/toolkit_C_PC_Linux_GCC_64bit.html Thanks for any guidance you can provide, 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.
Best way to use large C library in D as of 2024
Hi D I have a C library I use for work, it's maintained by an external organization that puts it through a very through test framework. Though source code is supplied, the intended use is to include the header files and link against pre-compiled code. What is the best way, as of 2024 to use this library with D, in particular dmd? ImportC doesn't seem like the go-to option since the C source does not need to be complied. I've seen some forum post indicating that manually generated D wrappers are no longer needed, but I'm fuzzy on the particulars. If there's any blog posts or other instructions you'd like to reference I'd be happy to check them out. For reference here's the C library in question: https://naif.jpl.nasa.gov/naif/toolkit_C_PC_Linux_GCC_64bit.html Thanks for any guidance you can provide,
Re: Hidden members of Class objects
On Thursday, 7 March 2024 at 00:38:30 UTC, Richard (Rikki) Andrew Cattermole wrote: Yes its opt-in. https://dlang.org/spec/statement.html#synchronized-statement As you mentioned in another thread there's handy ABI documentation for classes and interfaces just here [https://dlang.org/spec/abi.html#classes](https://dlang.org/spec/abi.html#classes) that spells out the story.
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: Why is this code slow?
On Monday, 25 March 2024 at 14:02:08 UTC, rkompass wrote: Of course you may also combine the up(+) and down(-) step to one: 1/i - 1/(i+2) = 2/(i*(i+2)) ```d double leibniz(int iter) { double n = 0.0; for (int i = 1; i < iter; i+=4) n += 2.0 / (i * (i+2.0)); return n * 4.0; } ``` or even combine both approaches. But of, course mathematically much more is possible. This was not about approximating pi as fast as possible... The above first approach still works with the original speed, only makes the result a little bit nicer. It's obvious that you are a good mathematician. You used sequence A005563. First of all, I must apologize to the questioner for digressing from the topic. But I saw that there is a calculation difference between real and double. My goal was to see if there would be a change in speed. For example, with 250 million cycles (iter/4) I got the following result: 3.14159265158976691 (250 5million (with real) 3.14159264457621568 (250 million with double) 3.14159265358979324 (std.math.constants.PI) First of all, my question is: Why do we see this calculation error with double? Could the changes I made to the algorithm have caused this? Here's an executable code snippet: ```d enum step = 4; enum loop = 250_000_000; auto leibniz(T)(int iter) { T n = 2/3.0; for(int i = 5; i < iter; i += step) { T a = (2.0 + i) * i; // https://oeis.org/A005563 n += 2/a; } return n * step; } import std.stdio : writefln; void main() { enum iter = loop * step-10; 65358979323.writefln!"Compare.%s"; iter.leibniz!double.writefln!"%.17f (double)"; iter.leibniz!real.writefln!"%.17f (real)"; imported!"std.math".PI.writefln!"%.17f (enum)"; } /* Prints: Compare.65358979323 3.14159264457621568 (double) 3.14159265158976689 (real) 3.14159265358979324 (enum) */ ``` In fact, there are algorithms that calculate accurately up to 12 decimal places with fewer cycles. (e.g. ) SDB@79
Re: Why is this code slow?
On Sunday, 24 March 2024 at 21:21:13 UTC, kdevel wrote: Usually you do not translate mathematical expressions directly into code: ``` n += pow(-1.0, i - 1.0) / (i * 2.0 - 1.0); ``` The term containing the `pow` invocation computes the alternating sequence -1, 1, -1, ..., which can be replaced by e.g. ``` immutable int [2] sign = [-1, 1]; n += sign [i & 1] / (i * 2.0 - 1.0); ``` This saves the expensive call to the pow function. I know that the code can be simplified/optimized, I just wanted to compare the same expression in C and D.
Re: request assistance resolving curl error
On Tuesday, 26 March 2024 at 07:13:24 UTC, confuzzled wrote: Hello all, I have two scripts. I copied the first directly from the alpaca website and massaged it with etc.c.curl until it compiled in D. The result is that it creates the order and returns the result to stdout. In the second script, I tried to use std.net.curl but cannot get it to work. I think you should use the HTTP interface, did you check this docs? https://dlang.org/phobos/std_net_curl.html#.HTTP https://dlang.org/phobos/std_net_curl.html#.HTTP.addRequestHeader Andrea
request assistance resolving curl error
Hello all, I have two scripts. I copied the first directly from the alpaca website and massaged it with etc.c.curl until it compiled in D. The result is that it creates the order and returns the result to stdout. In the second script, I tried to use std.net.curl but cannot get it to work. The only difference I can recognize between the two is that in the direct C version, CurlOption.writedata accepts a file handle and is passed stdout as in the example presented on alpaca's website while the wrapper accepts three different types (i.e., const(char)[], long, void*) and regardless of what I pass to it, nothing works. I tried to not setting it but that didn't work either. Don't know if that is even an option since alpaca_c did not work without it and resulted in the same error `{"code":4001,"message":"request body format is invalid"}`. **1. alpaca_c** ```d module alpaca_c; import etc.c.curl; import core.stdc.stdio: stdout; import std.conv: text; import config; pragma(lib, "curl"); int main() { CURL *hnd = curl_easy_init(); curl_easy_setopt(hnd, CurlOption.customrequest, "POST".ptr); curl_easy_setopt(hnd, CurlOption.writedata, stdout); curl_easy_setopt(hnd, CurlOption.url, "https://paper-api.alpaca.markets/v2/orders".ptr); curl_slist *headers = null; headers = curl_slist_append(headers, "accept: application/json"); headers = curl_slist_append(headers, "content-type: application/json"); headers = curl_slist_append(headers, i"APCA-API-KEY-ID: $(config.api_key)".text.ptr); headers = curl_slist_append(headers, i"APCA-API-SECRET-KEY: $(config.secret_key)".text.ptr); curl_easy_setopt(hnd, CurlOption.httpheader, headers); curl_easy_setopt(hnd, CurlOption.postfields, `{"side":"buy","type":"market","time_in_force":"day","qty":"1","symbol":"LCID"}`.ptr); CURLcode ret = curl_easy_perform(hnd); return 0; } ``` **2. alpaca_d** ```d import std.net.curl: Curl; import etc.c.curl: curl_slist, curl_slist_append, CurlOption; import core.stdc.stdio: stdout; import std.stdio: writeln; import std.conv: text; import config; pragma(lib, "curl"); void main() { string result; Curl c; c.initialize(); c.set(CurlOption.customrequest, "POST"); c.set(CurlOption.writedata, cast(void*) stdout); c.set(CurlOption.url, "https://paper-api.alpaca.markets/v2/orders;); string key = i"APCA-API-KEY-ID: $(config.api_key)".text; string secret = i"APCA-API-SECRET-KEY: $(config.secret_key)".text; curl_slist* headers; headers = curl_slist_append(headers, "accept: application/json"); headers = curl_slist_append(headers, "content-type: application/json"); headers = curl_slist_append(headers, [0]); headers = curl_slist_append(headers, [0]); c.set(CurlOption.httpheader, headers); c.set(CurlOption.postfields, `{"side":"buy","type":"market","time_in_force":"day","symbol":"LCID","qty":"1"}`); c.onReceive = (ubyte[] data) { result ~= data; return data.length; }; auto ret = c.perform(); writeln(result); } ``` Thanks for your assistance. --confuzzled