Parce que vous triez lexicalement, essayez ce code:
#!/usr/bin/perl
use strict;
use warnings;
my $ref = [ 5.0e-5,4.2e-5,4.3e-5,4.4e-5,4.4e-5,4.2e-5,4.2e-5,4.0e-5];
print "Perl with cmp\n";
for my $val (sort @$ref) {
printf "%f \n", $val;
}
print "Perl with <=>\n";
for my $val (sort { $a <=> $b } @$ref) {
printf "%f \n", $val;
}
print "C\n";
test($ref);
use Inline C => <<'END_OF_C_CODE';
void test(SV* sv, ...) {
I32 i;
I32 arrayLen;
AV* data;
float retval;
SV** pvalue;
Inline_Stack_Vars;
data = SvUV(Inline_Stack_Item(0));
/* Determine the length of the array */
arrayLen = av_len(data);
// sort
sortsv(AvARRAY(data),av_len(data)+1,Perl_sv_cmp_locale);
arrayLen = av_len(data);
for (i = 0; i < arrayLen+1; i++) {
pvalue = av_fetch(data,i,0); /* fetch the scalar located at i .*/
retval = SvNV(*pvalue); /* dereference the scalar into a number. */
printf("%f \n",newSVnv(retval));
}
}
END_OF_C_CODE
Bien sûr, lexicalement 0.00040
est plus petit que 0.00042
aussi bien, mais vous ne comparez pas 0.00040
-0.00042
; vous comparez le nombre 0.00040
converti en une chaîne avec le nombre 0.00042
converti en une chaîne. Quand un nombre devient trop grand ou trop petit, la logique de l'enchaînement de Perl recourt à la notation scientifique. Donc, vous triez l'ensemble des chaînes
"4.2e-05", "4.2e-05", "4.2e-05", "4.3e-05", "4.4e-05", "4.4e-05", "4e-05", "5e-05"
qui sont triés correctement. Perl retourne avec bonheur ces chaînes dans leurs nombres lorsque vous le demandez avec le format %f
en printf
. Vous pouvez vous-même codifier les chiffres, mais puisque vous avez déclaré que vous voulez que ce soit plus rapide, ce serait une erreur. Vous ne devriez pas essayer d'optimiser le programme avant de savoir où il ralentit (l'optimisation prématurée est la racine de tous les maux *
). Ecrivez votre code, puis exécutez Devel::NYTProf pour trouver où il est lent. Si nécessaire, réécrire ces parties dans XS ou Inline::C
(je préfère XS). Vous constaterez que vous obtenez plus de rapidité dans le choix de la bonne structure de données que des micro-optimisations comme celle-ci.
*
Knuth, Donald. Structured Programming with go to Statements, ACM Journal Computing Surveys, vol. 6, n ° 4, décembre 1974. p.268.
I aimerait avoir le tri dans la section Inline :: C pour la vitesse. Cela peut être le problème, mais comment truquer() pour trier numériquement n'est pas bien documenté. –
Vous n'en tirerez aucune vitesse. La fonction de tri en Perl est écrite en C. –
Maintenant, si vous voulez dire la fonction que vous passez à la fonction de tri, cela peut donner un coup de pouce à la vitesse, mais cela devrait être assez compliqué. –