NAME

Mojo::Collection::XS - Fast XS-based subclass of Mojo::Collection

SYNOPSIS

use Mojo::Collection::XS;

my $c = Mojo::Collection::XS->new(qw/foo bar baz/);

# Fast walk (aliases $_)
$c->while_fast(sub {
  say "$num: $_";
});

# Ultra-fast walk (never touches $_)
$c->while_ultra(sub ($e, $num) {
  say "$num: $e";
});

# Fast variants
$c->while_fast(sub ($e, $num) { ... });
$c->while_ultra(sub ($e, $num) { ... });
my $mapped = $c->map_fast(sub ($e) { uc $e });
my $mapped_ultra = $c->map_ultra(sub ($e) { $e });
my $filtered = $c->grep_fast(sub ($e) { $e =~ /foo/ });
$c->each_fast(sub ($e, $num) { ... });

DESCRIPTION

Mojo::Collection::XS is a subclass of Mojo::Collection with hot paths implemented in XS for better performance on large lists.

Callbacks must be code references; method-name strings are not supported.

METHODS

This class inherits all methods from Mojo::Collection and adds the following XS-backed helpers:

while_fast

$collection = $collection->while_fast(sub ($e, $num) {...});

Faster drop-in for "each" in Mojo::Collection when you need to walk the list and return the same collection. $_ is aliased to the current element, and $num is 1-based, matching the Perl implementation.

while_ultra

$collection = $collection->while_ultra(sub ($e, $num) {...});

Like "while_fast" but never touches $_ and minimizes stack work. Designed to be faster than "each" in Mojo::Collection (and far faster than a Perl while-loop with callbacks) while keeping the same argument order and return value.

map_fast

my $new = $collection->map_fast(sub ($e) { ... });

Faster equivalent of "map" in Mojo::Collection. The callback runs in list context, $_ is aliased, and the list return is flattened into a new collection of the same class.

map_ultra

my $new = $collection->map_ultra(sub ($e) { ... });

Scalar variant tuned for speed: no $_, minimal argument handling, and each scalar return value is gathered into a new collection of the same class. Built to beat "map" in Mojo::Collection and be significantly faster than Perl's native map for callback-heavy workloads.

grep_fast

my $new = $collection->grep_fast(sub ($e) { ... });

Faster equivalent of "grep" in Mojo::Collection. Call the callback for each element and include the original element in the resulting collection when the callback returns a true value. $_ is set to the current element (alias).

each_fast

$collection = $collection->each_fast(sub ($e, $num) {...});

Iterate over all elements, passing the element and its 1-based index to the callback. $_ is set to the current element (alias). Returns the same collection. This is a faster drop-in for "each" in Mojo::Collection.

CALLBACK COST

All helpers still invoke your Perl callbacks for every element. They reduce stack/aliasing overhead (e.g. while_ultra never touches $_), but the callback body dominates runtime. In real workloads (hash/object munging, I/O, JSON), the XS loops can help; in micro-benchmarks with trivial callbacks, the savings may be small or even reversed because call_sv overhead is the bottleneck.

COMBINING WITH Mojo::Collection

Mix the XS helpers with the rest of Mojo::Collection for readable pipelines:

map_fast with Mojo::Collection::grep/reduce

Heavy transforms in XS, aggregate in Perl:

my $sum = $collection->map_fast(sub { $_ * 2 })->grep(sub { $_[0] > 10 })->reduce(sub { $_[0] + $_[1] });

while_fast with Mojo::Collection::map/grep/to_array

Side effects in XS, render in Perl:

my $ids = $collection->while_fast(sub { $_->{seen} = 1 })->map(sub { $_[0]{id} })->to_array;

while_ultra with Mojo::Collection::map/to_array

Iterate without touching $_, then finish in Perl:

my $names = $collection->while_ultra(sub { $_[0]{score}++ })->map(sub { $_[0]{name} })->to_array;

map_ultra with Mojo::Collection::head/each

Fast scalar map, then light iteration:

my $top = $collection->map_ultra(sub { $_[0]{score} })->head(3); $top->each(sub { ... });

map_ultra with Mojo::Collection::uniq/size

Count unique values without touching $_:

my $count_unique = $collection->map_ultra(sub { $_[0]{id} })->uniq->size;

grep_fast with Mojo::Collection::map/join

Filter in XS, render in Perl:

my $csv = $collection->grep_fast(sub { $_->{active} })->map(sub { $_[0]{name} })->join(',');

each_fast with Mojo::Collection::sort/head

Quick mutation then ordering:

my $first = $collection->each_fast(sub { $_->{score} += 1 })->sort(sub { $_[0]{score} <=> $_[1]{score} })->head(1);

AUTHORS

Achmad Yusri Afandi, [ yusrideb at cpan.org ]

COPYRIGHT AND LICENSE

Copyright (C) 2025 by Achmad Yusri Afandi

This program is free software, you can redistribute it and/or modify it under the terms of the Artistic License version 2.0.