in reply to Fast Building of SQL Statements

This method is fast, as the following benchmark shows:

Yeah, but it's also wrong, as the following code shows:

#!/usr/bin/perl use strict; use warnings; use Benchmark qw( cmpthese ); my $count = shift || 100000; my @test_array = (0 .. 99); my (@array1, @array2); sub map_bench { @array1 = map { '?' } @test_array; } sub x_bench { @array2 = '?' x @test_array; } map_bench; x_bench; print "\@test_array has ", scalar @test_array, " elements\n"; print "\@array1 has ", scalar @array1, " elements\n"; print "\@array2 has ", scalar @array2, " elements\n"; __END__ @test_array has 100 elements @array1 has 100 elements @array2 has 1 elements

The x operator will only return a multi-element list if all of the following conditions are met:

And the last condition isn't met. Here's a better benchmark, x is still winning, but not with such a margin:
#!/usr/bin/perl use strict; use warnings; use Benchmark qw /cmpthese/; our @test_array = (0 .. 99); our (@array1, @array2); cmpthese -2 => { map => '@::array1 = map {"?"} @::test_array', x => '@::array2 = ("?") x @::test_array' }; die "Benchmark failed" unless @test_array == @array1 && @test_array == @array2; __END__ Benchmark: running map, x for at least 2 CPU seconds... map: 3 wallclock secs ( 2.09 usr + 0.03 sys = 2.12 CPU) @ 46 +08.49/s (n=9770) x: 2 wallclock secs ( 2.28 usr + 0.00 sys = 2.28 CPU) @ 14 +508.33/s (n=33079) Rate map x map 4608/s -- -68% x 14508/s 215% --

Abigail

Replies are listed 'Best First'.
Re: Re: Fast Building of SQL Statements
by zby (Vicar) on Aug 28, 2003 at 07:57 UTC
    To defend his technique I slightly modified his benchmarking script:
    #!/usr/bin/perl use strict; use warnings; use Benchmark qw( cmpthese ); my $count = shift || 100000; my @test_array = (0 .. 99); sub map_bench { my $result = join(', ', map { '?' } @test_array); } sub x_bench { my $result = '?, ' x @test_array; } cmpthese($count, { map => \&map_bench, x => \&x_bench, }); __END__ Benchmark: timing 100000 iterations of map, x... map: 28 wallclock secs (27.94 usr + 0.00 sys = 27.94 CPU) @ 35 +78.97/s (n=100000) x: 1 wallclock secs ( 0.77 usr + 0.00 sys = 0.77 CPU) @ 12 +9533.68/s (n=100000) Rate map x map 3579/s -- -97% x 129534/s 3519% --
    Update: Unfortunately I forgot about the first reason of using join - getting rid of the last comma. Perhaps it should be
    my $result = ('?, ' x $#test_array) . '?'
    It's not as elegant as it was. But still simpler than
    my $result = join(', ', map { '?' } @test_array);