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

pinwheel
 2020-01-05 01:13
#191060 #191060
User since
2015-07-11
3 Artikel
BenutzerIn
[default_avatar]
Hallo zusammen,

ich schreibe gerade einen Serialisierer für diverse Fahrplandatenformate. Am Besten beginne ich einmal mit einem möglichst weit eingedampften Minimalbeispiel:

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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#!/usr/bin/env perl

use strict;
use warnings;

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

# User Choice
my $fmt = $fmt2;
my $f   = 2;

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

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

sub get_line_1 {
    my ($dat1) = @_;

    return sprintf(
        $fmt,
        $dat1->{'a'},
        $dat1->{'b'},
        $dat1->{'c'},
        $dat1->{'d'}
    );
}

sub get_line_2 {
    my ($dat1, $dat2) = @_;

    return sprintf(
        $fmt,
        $dat2->{'a'},
        $dat2->{'b'},
        $dat1->{'a'}
    );
}


# Fake Code: Ich habe folgendes schon ausprobiert und weiß, dass es nicht
# funktioniert, aber ich hatte gehofft, dass eine Lösung in dieser Richtung
# existiert: Idealerweise ist es möglich die Argumente für die Formatstrings
# vorzuberechnen, das kriege ich aber leider nicht hin: Unten stehender Code
# liefert nur:
#      Useless use of a constant ("$dat1->{'a'}") in void context
#      Argument "$dat1->{'a'}" isn't numeric in sprintf
#
# my $arg1 = qw( $dat1->{'a'} $dat1->{'b'} $dat1->{'c'} $dat1->{'d'} );
# my $arg2 = qw( $dat2->{'a'} $dat2->{'b'} $dat1->{'a'} );
#
# my $arg = $arg2;
#
# sub get_line_wunsch {
#     my ($dat1, $dat2) = @_;
# 
#     return sprintf(
#         $fmt,
#         $arg
#     );
# }
#
# print get_line_wunsch($d, $e), "\n";

if($f == 1) {
    print get_line_1($d), "\n";
} else {
    print get_line_2($d, $e), "\n";
}


Die Funktionen get_line_* sind stark vereinfachte erzeugende Funktionen für die zu schreibenden Fahrplandaten. Im Konstruktor des Serialisierers kann der Aufrufer (in gewissen Grenzen) wählen, in welchem Format die Daten geschrieben werden sollen. Die sich aus dieser Wahl ergebenen Formatstrings kann ich vorberechnen (vereinfacht dargestellt durch $fmt1 und $fmt2 in o.a. Beispiel).

Diese Funktionen werden _viele_ Millionen mal pro Aufbereitung durchlaufen, so dass ich mir die Fallunterscheidung am Ende des Beispiels gerne sparen würde. Es ist nicht so einfach, die Komplexität der Bedingung in einem Minimalbeispiel unterzubringen, aber ich kann soviel sagen: Der Vergleich kostet bei Dateien mit >50 Mio Zeilen enorm viel Zeit. Davon abgesehen, wäre es natürlich viel eleganter, nur eine Funktion verwalten und aufrufen zu müssen :-)

Im Wesentlichen suche ich einfach nach einer Möglichkeit, nicht nur die Formatstrings, sondern auch die für die Argumente passenden Datenstrukturen vorberechnen zu können.

View full thread Formatstring und Argumente für sprintf vorberechnen