| 23 Dec 2025 | |||
| disbot7 | <antononcube> @librasteve Is there a performance page in raku.org ? Some of the points @Voldenet made above might be good to be there… | 13:04 | |
| Voldenet | ab5tract: is that implemented on nqp level? Because if not it wouldn't beat python's dictobject (which uses C) | 13:09 | |
| in nqp I can only find string-based hash | |||
| lizmat | there is only a string based hash | 13:14 | |
| all other hash types, such as object hashes, under the hood revert to a string | 13:15 | ||
| a hash with keys limited to Int, is basically an object hash with a constraint on the key | |||
| so slower | 13:16 | ||
| Voldenet | though in theory it is possible to implement hashtable in pure raku | 13:20 | |
| and in theory it doesn't have to be slower than C | 13:21 | ||
| lizmat | my reference to "so slower" is about the current implementation :-) | 13:24 | |
| now if objects of value types would share their unique values, we could use the object id as a key in the hash | 13:25 | ||
| but unfortunately, they don't | |||
| Voldenet | you can expect boring equality contract to be implemented | 13:26 | |
| hashCode + equals | |||
| disbot7 | <librasteve> @antononcube there is no performance page on raku.org --- the goal of raku.org is to convert new potential raku users, so doesn't really belong there imo --- I would support a Performance page in the docs (docs.raku.org/introduction) with an emphasis on how to avoid the pitfalls listed above. | 13:27 | |
| Voldenet | I remember TypedHash using .WHICH which usually requires some serialized string, I'm not sure if that's still valid | ||
| disbot7 | <librasteve> oh - there is one already => docs.raku.org/language/performance..._your_code | 13:28 | |
| <librasteve> so - suggest we gather anything missing and apply as a PR to that docs page | 13:29 | ||
| <librasteve> @simon_sibl - note the performance page in the docs ^^ | |||
| lizmat | Voldenet: that's how object hashes work | ||
| disbot7 | <librasteve> may help to improve, I have used the profiler from time to time | ||
| Voldenet | …wait, so does that mean that typed int hash is slower than regular hash? | 13:30 | |
| m: my %h is Hash[Int,Int]; for ^100 { %h{$_} = $_ + 2; }; say now - BEGIN now | |||
| camelia | 0.0347615 | ||
| Voldenet | m: my %h is Hash; for ^100 { %h{$_} = $_ + 2; }; say now - BEGIN now | 13:31 | |
| camelia | 0.015954565 | ||
| lizmat | yup | ||
| I once wrote raku.land/zef:lizmat/Hash::int | |||
| Voldenet | yeah, I remember, it was wildly faster because of nqp ops | ||
| lizmat | but I'm afraid the performance advantage has largely evaporated after the new dispatch | 13:32 | |
| Voldenet | I'm starting to wonder if `role Equatable` and regular list-based hashtable wouldn't be fast enough to beat string-based Hash for ints | 13:35 | |
| lizmat | I vaguely remember trying that... I think as soon as you hit 10+ keys, hashes were actually faster | 13:38 | |
| disbot7 | <antononcube> @librasteve The profiler has been pretty useless for me, lately. | 13:39 | |
| lizmat | the overhead of the MoarVM runloop quickly kicks in compared to C code that goes to the metal | ||
| Voldenet | eh so the only "sane" option would be having actual nqp objecthash | 13:40 | |
| or nativecall one | 13:41 | ||
| lizmat | well, the expensive thing is still the .WHICH calculation | ||
| which is HLL | |||
| Voldenet | .WHICH is actually not HASHCODE | ||
| it can't has collisions, hashcode can - this is actually big requirement for performance here | 13:42 | ||
| s/has/have/ | |||
| lizmat | well, a collision in .WHICH just means that two objects are going to be considered identical, even if they maybe aren't because of a deficiency in the .WHICH creation | 13:43 | |
| Voldenet | and that contract is insane for hashcode imo, this can never work well | 13:44 | |
| erm, for typed hash | |||
| WHICH basically does string serialization, so resulting strings has to be bigger and more inefficient | 13:49 | ||
| it could be faster in case where object would do a lot of dereferencing to get into data and all those pointers are non-cached anyhow | 13:50 | ||
| though I wouldn't bet on it being faster and smaller | 13:51 | ||
| hm, I'm going to test my assumptions and see if I can make it faster Hash using raku only | 13:55 | ||
| lizmat | yeah: I've done a lot of (perhaps premature) optimization in that area in the core | ||
| ++Voldenet looking forward to the results, even if they turn out to be negative! | |||
| Voldenet | if they turn out negative, I see if I can implement nqp::hashcode or something to make it fast enough | 13:56 | |
| I could also use tiny wrapper over std::unordered_map | 13:58 | ||
| I'm betting I can beat hashes if I punch the problem with enough C/C++ | |||