[मूल जवाब "सवाल के बाद से" करने के लिए नीचे 2008/11/27 के रूप में हैश मान का रीड की बचत होती है; 2008-11-29 के रूप में वहां से विश्लेषण नया है।]
सबसे तेज़ - सुनिश्चित नहीं है। यह काम करता है, हालांकि यह बहुत नहीं है:
#!/bin/perl -w
use strict;
my @mylist1;
push(@mylist1,"A");
push(@mylist1,"B");
push(@mylist1,"C");
my @mylist2;
push(@mylist2,"A");
push(@mylist2,"D");
push(@mylist2,"E");
sub value_in
{
my($value, @array) = @_;
foreach my $element (@array)
{
return 1 if $value eq $element;
}
return 0;
}
@mylist2 = (@mylist2, grep { ! value_in($_, @mylist2) } @mylist1);
print sort @mylist2, "\n";
इस हैश में सरणियों परिवर्तित करने से बचा जाता है - लेकिन बड़े सरणियों के लिए, value_in
उप धीमा हो सकता है।
चूंकि सवाल "सबसे तेज़ तरीका क्या है", मैंने कुछ बेंचमार्किंग की। मेरे किसी भी आश्चर्यजनक आश्चर्य के लिए, मेरी विधि सबसे धीमी थी। कुछ हद तक मेरे आश्चर्य की बात है, सबसे तेज़ तरीका सूची :: MoreUtils से नहीं था। मेरे मूल प्रस्ताव के एक संशोधित संस्करण का उपयोग कर परीक्षण कोड और परिणाम यहां दिए गए हैं।
#!/bin/perl -w
use strict;
use List::MoreUtils qw(uniq);
use Benchmark::Timer;
my @mylist1;
push(@mylist1,"A");
push(@mylist1,"B");
push(@mylist1,"C");
my @mylist2;
push(@mylist2,"A");
push(@mylist2,"D");
push(@mylist2,"E");
sub value_in
{
my($value) = shift @_;
return grep { $value eq $_ } @_;
}
my @mylist3;
my @mylist4;
my @mylist5;
my @mylist6;
my $t = Benchmark::Timer->new(skip=>1);
my $iterations = 10000;
for my $i (1..$iterations)
{
$t->start('JLv2');
@mylist3 = (@mylist2, grep { ! value_in($_, @mylist2) } @mylist1);
$t->stop('JLv2');
}
print $t->report('JLv2');
for my $i (1..$iterations)
{
$t->start('LMU');
@mylist4 = uniq(@mylist1, @mylist2);
$t->stop('LMU');
}
print $t->report('LMU');
for my $i (1..$iterations)
{
@mylist5 = @mylist2;
$t->start('HV1');
my %k;
map { $k{$_} = 1 } @mylist5;
push(@mylist5, grep { !exists $k{$_} } @mylist1);
$t->stop('HV1');
}
print $t->report('HV1');
for my $i (1..$iterations)
{
$t->start('HV2');
my %k;
map { $k{$_} = 1 } @mylist1;
map { $k{$_} = 1 } @mylist2;
@mylist6 = keys %k;
$t->stop('HV2');
}
print $t->report('HV2');
print sort(@mylist3), "\n";
print sort(@mylist4), "\n";
print sort(@mylist5), "\n";
print sort(@mylist6), "\n";
Black JL: perl xxx.pl
9999 trials of JLv2 (1.298s total), 129us/trial
9999 trials of LMU (968.176ms total), 96us/trial
9999 trials of HV1 (516.799ms total), 51us/trial
9999 trials of HV2 (768.073ms total), 76us/trial
ABCDE
ABCDE
ABCDE
ABCDE
Black JL:
यह पर्ल 5.10.0 एक प्राचीन सूर्य E450 पर बहुलता के साथ 32-बिट स्पार्क के लिए संकलित सोलारिस 10
मुझे विश्वास है कि परीक्षण सेटअप निष्पक्ष हैं चल रहा है; वे सभी अपना जवाब एक नई सरणी में उत्पन्न करते हैं, मेरी सूची 1 और mylist2 से अलग (इसलिए मेरी सूची 1 और mylist2 को अगले परीक्षण के लिए पुन: उपयोग किया जा सकता है)। एचवी 1 (हैश मान 1) नामित उत्तर में @ mylist5 के असाइनमेंट के बाद समय शुरू हो गया है, जो मुझे लगता है कि सही है। हालांकि, जब मैं काम से पहले शुरुआत के साथ समय किया था, यह अभी भी सबसे तेज था:
Black JL: perl xxx.pl
9999 trials of JLv2 (1.293s total), 129us/trial
9999 trials of LMU (938.504ms total), 93us/trial
9999 trials of HV1 (505.998ms total), 50us/trial
9999 trials of HV2 (756.722ms total), 75us/trial
ABCDE
ABCDE
ABCDE
ABCDE
9999 trials of HV1A (655.582ms total), 65us/trial
Black JL:
अगर आप मूल आदेश रखने के लिए की जरूरत नहीं है ठीक है। –
दूसरा विकल्प मेरे माप के अनुसार सबसे तेज़ है - और सूची :: MoreUtils में uniq विधि से तेज़ है। –