Re: Best way to use large C library in D as of 2024

2024-03-26 Thread bachmeier via Digitalmars-d-learn

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

2024-03-26 Thread Chris Piker via Digitalmars-d-learn

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

2024-03-26 Thread bachmeier via Digitalmars-d-learn

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

2024-03-26 Thread Chris Piker via Digitalmars-d-learn

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

2024-03-26 Thread Carl Sturtivant via Digitalmars-d-learn
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?

2024-03-26 Thread Lance Bachmeier via Digitalmars-d-learn

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?

2024-03-26 Thread Lance Bachmeier via Digitalmars-d-learn

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?

2024-03-26 Thread Salih Dincer via Digitalmars-d-learn

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?

2024-03-26 Thread Csaba via Digitalmars-d-learn

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

2024-03-26 Thread Andrea Fontana via Digitalmars-d-learn

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

2024-03-26 Thread confuzzled via Digitalmars-d-learn

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