🦋 Welcome to the MAIN() IRC channel of the Raku Programming Language (raku.org). Log available at irclogs.raku.org/raku/live.html . If you're a beginner, you can also check out the #raku-beginner channel!
Set by lizmat on 6 September 2022.
jdv rawley.xyz/perl-oo-action-benchmark.html 10:26
i thought raku was faster than perl in this sort of way
lizmat looks like the bottlenneck is in the hash creation on .execute 10:31
the code as is runs in 1.36 secs for me on an M1 10:32
without the call to .execute, it runs at .47 10:33
changing the contents of .execute to: "use nqp; nqp::hash('name',$!name, 'age', $!age);"
it runs at .58
looking at the QAST, it looks like it %(foo => 42, bar => 666) is codegenned as List.new( (Pair.new("foo",42), Pair.new("bar", 666) ).hash 10:39
so it's creating Pair objects, and a List object, and the coerces that into a hash: I think we will be able to do better in RakuAST :-) 10:40
Voldenet there's a few things wrong about this piece of code: `%(name => $!name, age => $!age)` 12:06
do you… actually need a lookup (hash represents a lookup)? 12:07
and is your data really that unstructured?
though the obvious optimization would be having constant keys hashtable for the piece of code, so hash is not recomputed 12:09
I think it could be done with Hash::Agnostic; 12:10
I do wonder though 12:11
m: class Action { method execute { return (name => "old man", age => 100) }}; for ^1000000 { Action.execute }; say now - BEGIN now 12:12
camelia 0.185289899
lizmat using hashes to represent information, is very perly
Voldenet m: class Action { class Result { has Str $.name; has Int $.age; }; method execute { return Result.new(name => "old man", age => 100) }}; for ^1000000 { Action.execute }; say now - BEGIN now 12:13
camelia 0.457651366
Voldenet …shouldn't the latter be faster? 12:14
lizmat replaced method execute by: method execute { Action.new(:$!name, :$!age) }
clocks in at .77 12:15
morale: use objects if you can, don't use ad-hoc hashes for structured data
Voldenet yeah, objects can be optimized well 12:16
and the api that has fixed Arguments and Result is going to be easier to document too 12:17
though I think ad-hoc classes could be made in cases like those, nodejs does that in similar case 12:18
so `%{ a => $a, b => $b }` becomes `class AdHocHash does DynamicHash { has $.a; has $.b; }; DynamicHash.new(:$a, :$b)` 12:20
because of that, nodejs seems 10x faster, only when adding dynamic member it becomes comparably slow 12:36
Voldenet (seems, because in case of nodejs it's harder to make a synthetic benchmark) 12:39
lizmat as I said, we can do better in RakuAST :-) 12:45
jdv how does ruby do it so fast 13:03
i mean sure, dont use hashes is nice. but ruby can do it and i bet php is even better at it... 13:05
leont Using ad-hoc hashes is a very common anti-pattern in scripting languages 13:09
One major feature of Raku is making it easier to create classes, which should make it less tempting to abuse a hash for something that should be an object 13:10
jdv even the sans hash runs take way longer 13:11
better than it was in the recent past at least i guess 13:13
jdv php 8.2 seems to have a solid effort - gist.github.com/jdv/d44522b6b80cf0...425a14290f 14:18
lizmat jdv: what happend if you increase the number of iterations x 10 and x 100 ? 14:54
*happens
Voldenet if you compare php with anything, do try 8.3 16:00
8.3 can be around 20-30% faster depending on use case 16:01
jdv i only bring up php cause its still "relevant" 16:02
sadly, perl is largely not anymore
Voldenet Probably because php is actively pursuing single use case, so all tradeoffs are targeted towards webhosting 16:03
jdv its a real competitor 16:04
oh, and wordpress;)
Voldenet yeah, wordpress on top of it 16:06
lizmat jdv: did you try 10x and 100x more iterations? 16:17
OOC, I wonder whether PHP decides that you're not doing anything with side-effects. so just noops the whole loop
jdv im "afk". i will in a bit:) 16:18
i printed from the constructor, the method, and the loop. but maybe that made it deopt... 16:19
my uneducated guess is fb poured money into php back in the day or something 16:20
MasterDuke for me a python version is the fastest. python 0.18s, ruby 0.29s, perl 0.86s, raku 1.45s 16:21
jdv ah. a new datapoint. wonder what python is doing... 16:22
MasterDuke and jdv's php version was 0.15s
jdv geez
MasterDuke oh wait, let my check my python 16:23
jdv woukdnt surprise me though. worked with php 7 and it was pretty speedy.
lizmat the slow part is really the Hash creation 16:24
MasterDuke huh. apparently i've forgotten python in the last year and a half 16:25
gist.github.com/MasterDuke17/d5d07...27c87f6073 doesn't print anything 16:26
jdv think they got a jit recently
with fancy ea the hash is constant. id guess php is doing that. 16:27
Voldenet I'd check golang, but dynamic result might need `map[string]interface{}` which is really not how it's supposed to be used 16:36
and using struct result is against rules :>
probably nodejs is going to wipe the floor with anything else pastebin.com/sabMqAgf 16:38
jdv $$$
Voldenet in nodejs you don't use $ in variables, because it all went into optimizations 16:39
:>
jdv but error handling isnt as fun
;)
Voldenet Oh, perhaps nqp-js could be good in this case 16:41
lizmat pretty sure that NQP on MoarVM would also be pretty fast 16:46
jdv cool 16:52
Voldenet nqp::hash was demonstrated to be over 2x faster, so it's very likely 16:55
lizmat the NQP version runs at .64 for me
jdv nice 16:56
lizmat gist.github.com/lizmat/1ac46215b6a...fa15763683
what I find odd is that that is slower than the Rakudo version with nqp::hash 16:57
I guess the rakudo static optimizer is a bit smarter still 16:58
[Coke] anyone using Terminal::Print? 17:50
lizmat And yet another Rakudo Weekly News hits the Net: rakudoweekly.blog/2024/02/19/2024-...completed/ 18:08
Voldenet nqp being slower is slightly unexpected 19:10
lizmat indeed 19:32
chemitz so `my uint64 $a = 9223372036854775808 ;my uint64 $b = 5919231096550412837; print $a +^ $b;` does not work but `my uint64 $a = 9223372036854775808 ;my uint64 $b = 5919231096550412837; print $a .Int +^ $b;` works.  Yet, I think `+^` promotes its operands to Int according to the documentation. 20:00
Voldenet the situation is somewhat weird, because uint64 is Int 20:01
m: say uint64 ~~ Int 20:02
camelia True
chemitz sorry typo above it should be `my uint64 $a = 9223372036854775808 ;my uint64 $b = 5919231096550412837; print $a.Int +^ $b;` for the second code snippet 20:03
Voldenet > multi sub infix:<+^>( int $a, int $b –> int) { nqp::bitxor_i($a, $b) } 20:05
> multi sub infix:<+^>(uint $a, uint $b –> uint) { nqp::bitxor_i($a, $b) }
github.com/rakudo/rakudo/blob/main...kumod#L535 20:06
So apparently there's no bitxor_i variant for uint
gfldex m: my uint64 $a = 9223372036854775808; say $a.WHAT; 20:30
camelia (Int)
chemitz Are these operations implemented in MoarVM? Is this missing variant by design, or may eventually be implemented later? 20:31
gfldex 9223372036854775808 is an Int literal, not an int. And `my uint64` does not coerce Int to uinit64. Right now there is no good way to do what you want to do. (Without going through buff, what introduces other difficulties.) 20:32
m: my uint64() $a = 9223372036854775808; # sadly, this does not work
camelia Cannot find method 'is_dispatcher' on object of type BOOTCode
in block <unit> at <tmp> line 1
gfldex chemitz: please note: github.com/rakudo/rakudo/pull/5526 20:33
gfldex And even with lizmat`s work, there are no typed exceptions on failing to convert Int to int. As they are thrown by MoarVM. 20:36
chemitz yeah I built and run this PR. I am trying to rewrite some SHA3 code to be faster, trying uint64 (conscious that I will hit issues with boxing/unboxing). 20:36
but I am hitting issues with uint64 handling (one of which was solved by this PR) 20:38
gfldex m: use nqp; dd nqp::coerce_iu(9223372036854775808); 20:40
camelia Cannot unbox 64 bit wide bigint into native integer
in block <unit> at <tmp> line 1
chemitz with the patch I can do ` my uint64 $a = 9223372036854775808.uint64 ;my uint64 $b = 5919231096550412837.uint64; print $a +^ $b;`  but I am still getting a negative result. 20:59
gfldex chemitz: That is hardly surprising, given: github.com/rakudo/rakudo/blob/3d18...kumod#L330 21:02
chemitz: please try nqp::bitxor_i 21:03
lizmat: please take note of ^^^ 21:04
MasterDuke chemitz: fyi, native uint* was implemented much later than the signed native types. nine++ did a lot of work a couple years ago to dramatically improve the uint situation. however, there are still some missing things. so rakudo issues would be helpful 21:07
MasterDuke oops, correct python time was 0.27s. so just about the same as ruby 22:22
jdv lizmat: sorry - got distracted. the php tracks. x10 takes as much longer as does x100. peculliarly x1000 is a mmap failure. idk bout that one:) 22:58