Thread Formatstring und Argumente für sprintf vorberechnen (11 answers)
Opened by pinwheel at 2020-01-05 01:13

haj
 2020-01-05 11:46
#191063 #191063
User since
2015-01-07
551 articles
BenutzerIn

user image
Es natürlich richtig, teuren Code nicht viele Millionen mal auszuführen, sondern nur einmal vorbereitend. Aber: Entscheidungen mit if für einfache Skalare sind um ein vielfaches schneller als beispielsweise ein einziger Zugriff auf ein Hash-Element. Die Fallunterscheidung nur dann ein Performance-Problem, wenn es sich um etwas wie if (zeitraubende_funktion($f)) { ... } handelt, aber bei einer einfachen "User Choice" ist, scheint mir das nicht der Fall zu sein. Wo die Zeit tatsächlich draufgeht, kann man sehr schön mit CPAN:Devel::NYTProf ermitteln.

Ansonsten kannst Du beispielsweise die Funktion get_line_wunsch abhängig von der "User Choice" generieren. Das ist kürzer, aber ich bin mir ziemlich sicher, dass es auch langsamer ist. Es muss ja nach wie vor für jeden Datensatz die Auswahl der zu druckenden Felder vorgenommen werden.
Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#!/usr/bin/env perl

use strict;
use warnings;
use 5.016;

my $fmt1 = "%09d %09d %5d %5d";
my $fmt2 = "#%-3d #%-3d %09d";

# User Choice
my $f   = $ARGV[0] // 1;

my $d = {
    'a' => 123,
    'b' => 456,
    'c' => 54321,
    'd' => 98765
};

my $e = {
    'a' => 789,
    'b' => 987
};

sub get_line_wunsch_factory {
    my ($f) = @_;
    my ($fmt,$arg_extractor);
    if ($f == 1) {
        $fmt = $fmt1;
        $arg_extractor = sub {
            my ($dat1) = @_;
            return (@$dat1{qw(a b c d)});
        }
    }
    elsif ($f == 2) {
        $fmt = $fmt2;
        $arg_extractor = sub {
            my ($dat1, $dat2) = @_;
            return ($dat2->{'a'},$dat2->{'b'},$dat1->{'a'});
        }
    }
    else {
        die "Fuer f = $f habe ich kein Format\n";
    }
    return sub {
        return sprintf($fmt,&$arg_extractor(@_));
    }
}

my $get_line_wunsch = get_line_wunsch_factory($f);

print &$get_line_wunsch($d,$e),"\n";


Zu Deinem Fake Code:
Quote
Code (perl): (dl )
my $arg1 = qw( $dat1->{'a'} $dat1->{'b'} $dat1->{'c'} $dat1->{'d'} );
An der Zeile sind zwei Dinge falsch:
  • mit qw ("quote words") werden die durch Leerzeichen getrennten Argumente in eine Liste eingetragen, eine Interpolation von Variablen findet dabei nicht statt. Die Listenelemente sind also einfach die Strings, zum Beispiel $dat1->{'a'}. Perl warnt zu Recht, dass dieser String nicht numerisch ist.
  • qw gibt eine Liste zurück, Du weist sie einem Skalar zu. In dem Fall wird $arg1 das letzte Element der Liste zugewiesen, also der String '$dat1->{'d'}'. Alle anderen sind das, was Perl Useless use of a constant nennt.

View full thread Formatstring und Argumente für sprintf vorberechnen