Améliorer l’efficacité d’un programme de sorting; affichage du sorting de la colonne% d’achèvement dans le terminal

J’ai un grand fichier d’entrée délimité par des tuyaux d’environ 6 millions de lignes, comme ci-dessous:

24|BBG000SJFVB0|EQ0000000009296012|OI SA-ADR|OIBR/C|US|ADR|Equity 16|BBG002PHVB83|EQ0000000022353186|BLOOM SELECT INCOME FUND|BLB-U|CT|Closed-End Fund|Equity -50|BBG000V0TN75|EQ0000000010271114|MECHEL-PREF SPON ADR|MTL/P|US|ADR|Equity 20|BBG002S0ZR60|EQ0000000022739316|DIVIDEND 15 SPLIT CORP II-RT|DF-R|CT|Closed-End Fund|Equity -20|BBG001R3LGM8|EQ0000000017879513|ING FLOATING RATE SENIOR LOA|ISL/U|CT|Closed-End Fund|Equity 0|BBG006M6SXL2|EQ0000000006846232|AA PLC|AA/|LN|Common Stock|Equity 

Les exigences sont comme ci-dessous:
1. Je dois sortinger ce fichier d’entrée par 1ère colonne puis 2ème colonne et ensuite 2ème dernière colonne dans cet ordre
2. Affichage du% d’achèvement du sorting dans le terminal / la console pour, par exemple, “colonne 2 sorting 75%”
3. enfin la sortie dans un fichier séparé.

J’ai écrit le programme ci-dessous qui sortinge parfaitement par 1ère colonne. Mais comment intégrer toutes les autres conditions? De plus, cela prend maintenant un peu plus de temps à courir. Y a-t-il une manière plus efficace et plus propre de le faire? La seule chose est que nous ne pouvons pas utiliser de paquetage externe supplémentaire de CPAN. Les solutions Unix comme l’utilisation de SED / AWK sont correctes, mais Perl est préférable.Je viens de savoir que Python intégré est également disponible pour que cette solution soit également la bienvenue.

 my (%link_strength); {$data="datascope_input.txt"; $out="sort_file.txt"; open (my $indata , '', $out)|| die "could not open $out :\n$!"; select $outdata; my @array=(); for (@array){ $link_strength{$1}=$_ if /(?:[^|]+\|){0}([^|]+)/; } print $link_strength{$_} for (sort {$a$b} keys %link_strength); close ($outdata); close ($indata); } 

À partir de vos exemples de données, vous allez sortinger environ 950 Mo. Il faudra 9,5 secondes de lecture à partir de la HD normale (100 Mo / s). Je ne sais pas à quelle vitesse il sera sortingé par type standard mais de mon expérience, il peut aller de 1 à 3 millions d’enregistrements par cœur de processeur. Disons 1 million. Il faudra 3 secondes sur le dual core et moins sur un serveur avec plus de cœurs de processeurs. Je pense que le plus de temps prendra la lecture et l’parsing de vos données. Si simple

 pv -p your_file.dat | sort -t'|' -k '1n,1' -k '2d,2' -k '14,14' 

devrait faire la plupart des fonctionnalités requirejses.

Comme je l’ai dit dans les commentaires, le sorting du système Linux / Unix est susceptible de donner de meilleurs résultats, mais si vous voulez vraiment Perl, cela fera l’affaire:

 use ssortingct; sub main { open F, 'input.txt' or die $!; my @pairs; while () { my @fields = split(/\|/); my $key = [ @fields[0, 1, -2] ]; push @pairs, [$key, $_]; } close F; my @sorted_pairs = sort { my $a_key = $a->[0]; my $b_key = $b->[0]; $a_key->[0] <=> $b_key->[0] || $a_key->[1] cmp $b_key->[1] || $a_key->[2] cmp $b_key->[2] } @pairs; foreach my $pair (@sorted_pairs) { print $pair->[1]; } } main; 

Aussi, comme je l’ai dit dans les commentaires, je ne sais pas comment recueillir de manière introspective des informations sur les progrès. Vous pouvez pirater quelque chose en comptant combien de comparaisons ont eu lieu, mais comme vous ne serez jamais sûr du nombre final, un pourcentage complet ne peut pas être calculé.