Re: Help optimize D solution to phone encoding problem: extremely slow performace.

2024-01-14 Thread Sergey via Digitalmars-d-learn

On Sunday, 14 January 2024 at 17:11:27 UTC, Renato wrote:
If anyone can find any flaw in my methodology or optmise my 
code so that it can still get a couple of times faster, 
approaching Rust's performance, I would greatly appreciate 
that! But for now, my understanding is that the most promising 
way to get there would be to write D in `betterC` style?!


I've added port from Rust in the PR comment. Can you please check 
this solution?
Most probably it need to be optimized with profiler. Just 
interesting how close-enough port will work.


Re: Socket handle leak and active handle warning with Vibe-D

2024-01-14 Thread Steven Schveighoffer via Digitalmars-d-learn

On Saturday, 13 January 2024 at 20:49:54 UTC, bomat wrote:

I am still getting this in 2024 and vibe.d 0.9.7:
```
Warning: 1 socket handles leaked at driver shutdown.
```

I was wondering if maybe someone has new info on this...


There should be a version you can enable that tells you where 
that socket handle was allocated. That might give you a further 
clue as to why it's not closed when the system shuts down.


I think the program tells you which version to enable when this 
happens, but if not, let me know and I'll find it.


-Steve


Re: Non-blocking keyboard input

2024-01-14 Thread Steven Schveighoffer via Digitalmars-d-learn

On Sunday, 14 January 2024 at 13:41:26 UTC, Joe wrote:

This does not actually work on my computer. It still blocks.


Adam is no longer using mainstream D, and apparently not posting 
on this forum.


I suggest you try to contact him via the arsd github page:

https://github.com/adamdruppe/arsd

-Steve


Re: Help optimize D solution to phone encoding problem: extremely slow performace.

2024-01-14 Thread Renato via Digitalmars-d-learn

On Sunday, 14 January 2024 at 10:02:58 UTC, Jordan Wilson wrote:

On Saturday, 13 January 2024 at 11:03:42 UTC, Renato wrote:
I like to use a phone encoding problem to determine the 
strenghtness and weaknesses of programming languages because 
this problem is easy enough I can write solutions in any 
language in a few hours, but complex enough to exercise lots 
of interesting parts of the language.


[...]


Hello Renato,

This seems to be quite a lot of calls:
```
 Timer frequency unknown, Times are in Megaticks 



  Num  TreeFuncPer
  CallsTimeTimeCall

1920496437613756   0 pure nothrow 
ref @trusted immutable(char)[][] 
core.internal.array.appending._d_arrayappendcTX!(immutable(char)[][], immutable(char)[])._d_arrayappendcTX(scope return ref immutable(char)[][], ulong)


1920492489573474   0 @safe void 
dencoder.printTranslations(immutable(char)[][][dencoder.Key], 
dencoder.ISolutionHandler, immutable(char)[], 
immutable(char)[], immutable(char)[][])

```

This is when using the `words-quarter.txt` input (the 
`dictionary.txt` input seems to finish much faster, although 
still slower than `java`/`rust`).


I also used only 100 phone numbers as input.

My final observation is that `words-quarter.txt` contains some 
1-letter inputs, (for example, `i` or `m`)...this may result in 
a large number of encoding permutations, which may explain the 
high number of recursion calls?


Jordan


The characteristics of the dictionary impact the number of 
solutions greatly. I explored this in my blog post about [Common 
Lisp, Part 
2](https://renato.athaydes.com/posts/revenge_of_lisp-part-2).


The fact there's a ridiculous amount of function calls is why 
this problem can take minutes even without having to allocate 
much memory or print anything.


** I've managed to improve the D code enough that it is now 
faster than Common Lisp and the equivalent algorithm in Java.**


It took some profiling to do that, though... thanks to 
@Anonymouse for the suggestion to use Valgrind... with that, I 
was able to profile the code nicely (Valgrind works nicely with 
D, it doesn't even show mangled names!).


Here's what I did.

First: the solution using int128 was much faster than the BigInt 
solution, as I had already mentioned. But when profiling that, it 
was clear that for the problems with a very large number of 
solutions, GC became a problem:


```

23,044,096,944 (100.0%)  PROGRAM TOTALS


Ir  file:function

7,079,878,197 (30.72%)  
???:core.internal.gc.impl.conservative.gc.Gcx.mark!(false, true, 
true).mark(core.internal.gc.impl.conservative.gc.Gcx.ScanRange!(false).ScanRange) [/home/renato/programming/experiments/prechelt-phone-number-encoding/dencoder-int128]
2,375,100,857 (10.31%)  
???:dencoder.printTranslations(immutable(char)[][][std.int128.Int128], dencoder.ISolutionHandler, immutable(char)[], immutable(char)[], immutable(char)[][])'2 [/home/renato/programming/experiments/prechelt-phone-number-encoding/dencoder-int128]
1,971,210,820 ( 8.55%)  ???:_aaInX 
[/home/renato/programming/experiments/prechelt-phone-number-encoding/dencoder-int128]
1,922,961,924 ( 8.34%)  ???:_d_arraysetlengthT 
[/home/renato/programming/experiments/prechelt-phone-number-encoding/dencoder-int128]
1,298,747,622 ( 5.64%)  ???:core.int128.mul(core.int128.Cent, 
core.int128.Cent) 
[/home/renato/programming/experiments/prechelt-phone-number-encoding/dencoder-int128]
1,134,644,706 ( 4.92%)  
???:core.internal.gc.bits.GCBits.setLocked(ulong) 
[/home/renato/programming/experiments/prechelt-phone-number-encoding/dencoder-int128]
  849,587,834 ( 3.69%)  
???:core.internal.gc.impl.conservative.gc.Gcx.smallAlloc(ulong, 
ref ulong, uint, const(TypeInfo)) 
[/home/renato/programming/experiments/prechelt-phone-number-encoding/dencoder-int128]
  827,407,988 ( 3.59%)  
./string/../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:__memcpy_avx_unaligned_erms [/usr/lib/x86_64-linux-gnu/libc.so.6]
  688,845,027 ( 2.99%)  
./string/../sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S:__memset_avx2_unaligned_erms [/usr/lib/x86_64-linux-gnu/libc.so.6]
  575,415,884 ( 2.50%)  
???:_DThn16_4core8internal2gc4impl12conservativeQw14ConservativeGC6qallocMFNbmkMxC8TypeInfoZSQDd6memory8BlkInfo_ [/home/renato/programming/experiments/prechelt-phone-number-encoding/dencoder-int128]
  562,146,592 ( 2.44%)  
???:core.internal.gc.impl.conservative.gc.ConservativeGC.runLocked!(core.internal.gc.impl.conservative.gc.ConservativeGC.mallocNoSync(ulong, uint, ref ulong, const(TypeInfo)), core.internal.gc.impl.conservative.gc.mallocTime, core.internal.gc.impl.conservative.gc.numMallocs, ulong, uint,

Re: Non-blocking keyboard input

2024-01-14 Thread Joe--- via Digitalmars-d-learn
On Wednesday, 27 December 2023 at 13:27:53 UTC, Adam D Ruppe 
wrote:

On Wednesday, 27 December 2023 at 05:07:04 UTC, Joe wrote:
??? Surely there there is 
a one liner library solution  for this?


It is not one line because it needs a bit of setup (and 
teardown, but the objects' destructors do that for you) but it 
is close:


http://arsd-official.dpldocs.info/arsd.terminal.html#single-key

`input.getch` waits for a single line, but you can use 
`if(input.kbhit())` to see if it would block before calling it.



This shouldn't be hard... yet it is.


Better be careful, the mods are out in force deleting posts 
this week that tell the hard truth. But yeah, the stdlib in D 
has very little activity:


https://github.com/dlang/phobos/graphs/contributors?

So you can't expect much from it. My arsd libs provide a broad 
set of functionality missing from it: stuff like this 
terminal/console stuff, window creation, basic guis, web 
servers, etc.


If you want to try them, you can use it from the dub system, 
but I recommend just `git clone 
https://github.com/adamdruppe/arsd.git` in your working 
directory then import what you want and use `dmd -i` to 
automatically include them in the build.


This does not actually work on my computer. It still blocks.


int itr = 0;
for(;;)
{
itr++;
			writeln("1. closeKBThread = ", closeKBThread, ", iter = ", 
itr);

if (closeKBThread) return;


string op = "";
string istr = "";
while (!closeKBThread)
{
writeln("2. ", input.kbhit(), " ", 
closeKBThread);

if (input.kbhit())
{   

istr ~= input.getch(false);
break;
}   
}
writeln("final istr = ", istr);


1. closeKBThread = false, iter = 1
2. false false
2. false false
2. false false
2. false false
final istr = f
1. closeKBThread = false, iter = 2
2. false false < now blocking

All this is just junk of me trying to figure out what was going 
on, but literally input.kbhit blocks after the first run(which 
really  means it's always blocking)


My original code was

while(true)
{
if (input.kbhit()) { istr ~= input.getch(); break; }
}

and I've been trying all kinds of stuff to figure out what was 
going on but I believe it is the kbhit function itself. It calls 
getch(true) and blocks on that as if I were just using getch 
itself.


The issue is the same, the code does not block then after I hit a 
key and it goes through an iteration of the outside loop it then 
blocks waiting for the next input.














Re: Help optimize D solution to phone encoding problem: extremely slow performace.

2024-01-14 Thread Renato via Digitalmars-d-learn

On Saturday, 13 January 2024 at 23:20:32 UTC, Sergey wrote:

On Saturday, 13 January 2024 at 19:35:57 UTC, Renato wrote:

On Saturday, 13 January 2024 at 17:00:58 UTC, Anonymouse wrote:

On Saturday, 13 January 2024 at 12:55:27 UTC, Renato wrote:

[...]
I will have to try it... I thought that `BigInt` was to blame 
for the slowness (from what I could read from the trace logs), 
but after replacing that with basically a byte array key (see 
[commit 
here](https://github.com/renatoathaydes/prechelt-phone-number-encoding/commit/0e9025b9aacdcfef5a2649be4cc82b9bc607fd6c)) it barely improved. It's still much slower than Common Lisp and very, very far from Java and Rust.


In the repo is hard to find the proper version.
I've checked the Rust from master branch and it looks a bit 
different from D implementation..


I explicitly linked to the Rust implementation in my question:

 the [Rust 
solution](https://github.com/renatoathaydes/prechelt-phone-number-encoding/blob/fastest-implementations-print-or-count/src/rust/phone_encoder/src/main.rs) uses approx. the same algorithm as used in CL and D, but instead of BigInt, it uses a Vec as key


Can you be more specific about which part of the Rust 
implementation is not roughly equivalent to the D 
implementation?? There are obvious differences in style and 
syntax, but I hope that it's mostly equivalent algorithm-wise.


But to clarify: the branch where the fastest solutions are is 
called `fastest-implementations-print-or-count`.


The D branches with my alternative implementations are all called 
`dlang-*`.




I would suggest to rewrite in the same way as Rust implemented.
Probably you would like to try:
* do not use BigInt from std. It could be quite slow. Try to 
use GMP library from Dub instead


Right, but as I posted above, even using a byte-array just like 
in Rust, the performance was still very bad (but around 2x faster 
than using BigInt).


Also, using GMP is always suggested to me, but I can't accept 
that because my goal is not to use C libraries to achieve the 
fastest speed (which I could do by using C or FFI in any other 
language), it's to use D (and the other languages) to solve my 
problem in an idiomatic way.


I [ended up using 
`Int128`](https://github.com/renatoathaydes/prechelt-phone-number-encoding/commit/98dcbcf1c77d1ded3406cc03af9026e126df5b2d) (the problem description requires more than i64, but int128 is enough), which grealy improved performance over my D baseline AND on the byte-array solution.



* don't do "idup" every time
* instead of byLine, try byLineCopy


`idup` is necessary because the strings are stored in a Map after 
the iteration ends. Anyway, I replaced that with `byLineCopy` and 
it became sligthtly slower.


* instead of "arr ~= data" try to use Appender 
(https://dlang.org/library/std/array/appender.html)


I was worried about `~=` allocating too much, though IIUC it 
shouldn't be a problem the way I used it... in any case, I 
[replaced it with 
`Appender`](https://github.com/renatoathaydes/prechelt-phone-number-encoding/commit/f1364d0897f1f37882f1d39b92c16b84b1abdc31) and the performance was completely unchanged - which is good as I think it means I used `~=` correctly to avoid overallocation (or I messed up using `Appender` :D - pls have a look).


* also you could try to use splitter 
(https://dlang.org/library/std/algorithm/iteration/splitter.html) to lazily process each part of the data


This is not necessary because that would only affect the time 
spent loading the dictionary, which is the faster part of the 
problem... nearly all of the time is spent looking for solutions 
instead.


* isLastDigit function has many checks, but I think it could be 
implemented easier in a Rust way


The Rust solution uses sum types for that, but that had a very 
minor effect on the overall performance (though in Rust, that's 
"cleaner" to use anyway)... I know D does have SumType in the 
stdlib, but I thought it is not as "zero cost" as in Rust, and 
because both variants wrap a String, it's awkward to use that... 
so I instead tried using a struct like this:


```d
struct WordOrDigit {
string value;
bool isDigit;
}
```

You can check [the commit 
here](https://github.com/renatoathaydes/prechelt-phone-number-encoding/commit/0f6b4ce83373c46b14b5bb40c53bb0e2d0905e66).


This change made the code slightly slower.

* also consider to use functions from Range (filter, map) as 
you use it in Rust, instead of using for loops


Why would for loops be slower? Or you're just saying I should 
make the D code nicer?


Anyway, thanks for the suggestions!


On Sunday, 14 January 2024 at 08:33:24 UTC, Anonymouse wrote:

On Saturday, 13 January 2024 at 23:20:32 UTC, Sergey wrote:

I would suggest to rewrite in the same way as Rust implemented.
Probably you would like to try:
[...]


I would strongly argue for profiling first instead of 
optimising based on conjecture. If you profile you have solid 
evidence on what is actually slow. I

Re: Help optimize D solution to phone encoding problem: extremely slow performace.

2024-01-14 Thread Jordan Wilson via Digitalmars-d-learn

On Saturday, 13 January 2024 at 11:03:42 UTC, Renato wrote:
I like to use a phone encoding problem to determine the 
strenghtness and weaknesses of programming languages because 
this problem is easy enough I can write solutions in any 
language in a few hours, but complex enough to exercise lots of 
interesting parts of the language.


[...]


Hello Renato,

This seems to be quite a lot of calls:
```
 Timer frequency unknown, Times are in Megaticks 

  Num  TreeFuncPer
  CallsTimeTimeCall

1920496437613756   0 pure nothrow ref 
@trusted immutable(char)[][] 
core.internal.array.appending._d_arrayappendcTX!(immutable(char)[][], immutable(char)[])._d_arrayappendcTX(scope return ref immutable(char)[][], ulong)


1920492489573474   0 @safe void 
dencoder.printTranslations(immutable(char)[][][dencoder.Key], 
dencoder.ISolutionHandler, immutable(char)[], immutable(char)[], 
immutable(char)[][])

```

This is when using the `words-quarter.txt` input (the 
`dictionary.txt` input seems to finish much faster, although 
still slower than `java`/`rust`).


I also used only 100 phone numbers as input.

My final observation is that `words-quarter.txt` contains some 
1-letter inputs, (for example, `i` or `m`)...this may result in a 
large number of encoding permutations, which may explain the high 
number of recursion calls?


Jordan



Re: Help optimize D solution to phone encoding problem: extremely slow performace.

2024-01-14 Thread Anonymouse via Digitalmars-d-learn

On Saturday, 13 January 2024 at 23:20:32 UTC, Sergey wrote:

I would suggest to rewrite in the same way as Rust implemented.
Probably you would like to try:
[...]


I would strongly argue for profiling first instead of optimising 
based on conjecture. If you profile you have solid evidence on 
what is actually slow. If you're very good at analysing D, 
well-educated hypotheses *may* be enough, until they suddenly 
aren't and you will have spent a lot of time on the wrong problem.