in reply to Adjusting variable context when workign with JSON data?

I also saw a video about how the JSON module in Perl is quite slow, could that be it?

No, because you are not using the JSON module, you are using the JSON::XS module. The two are quite different and the latter is purposely much faster than the former. And even if it weren't we are not talking about a particularly large chunk of JSON to decode.

I have not profiled your Perl code because as posted it fails to compile:

Missing right curly or square bracket at 11162986.pl line 36, at end o +f line syntax error at 11162986.pl line 36, at EOF 11162986.pl had compilation errors.

While I can guess what is wrong, this shows that the code you have posted is not the code you are running, so who knows what else might actually be in there to slow it down.

Regardless, a fair guess would be that the slow part is this line:

my $result = qx{ i3-msg -t get_workspaces }; # returns [{},{},{}]

Shelling out 100 times is going to be slow however you do it. Try obtaining the JSON once and then loop 100 times over the rest of the processing and see what difference that makes.


🦛

Replies are listed 'Best First'.
Re^2: Adjusting variable context when working with JSON data?
by unmatched (Sexton) on Dec 03, 2024 at 21:31 UTC

    Oops, I think I accidentally removed that closing curly brace for the loop there. I originally posted the without using any HTML tags and went back to adjust the post manually... got a little too carried away.

    You are probably right, spawning new processes is always expensive, and making this only once shows that Perl runs much faster. I would like to play with hyperfine as suggested above, so I might try that when I have something a bit more meaningful to test on.

    The "benchmark" was just for fun, thought, to see how Python and Perl compare. What I'm more concerned is with the correctness of the script, specifically how the JSON is processed. As I said, I find this syntax a bit strange: (@$decoded). I couldn't figure it out without looking for answers online and I'm not sure if there's perhaps a better way to tell Perl that this is an array (assuming that I know in advance the structure of the JSON to be returned)?

      You can start with an array at the beginning:
      my @decoded = @{ decode_json($result) };
      map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]

        I like that you can do this, duly noted. Thanks!

        I find this syntax a bit strange: (@$decoded)

      That's something you will have to get used to as it's a fundamental syntax in perl. $decoded is a reference to an array. To dereference it you just put a @ at the front. e.g. $x = [1,2,3]; @array = @$x. You can also put squiggles around the reference if that makes it clearer and in some cases this is needed, like @{$decoded}.

        I thought that you "\" to de-reference, or maybe that's just for hashes? But in any case I think you're right, I need to write some more Perl to get used to this. I've only started to pick it up out of curiosity, and so far I've only written a few things here and there to get a taste of the basics. Thanks for the help!