Schrift
Wiki:Tipp zum Debugging: use Data::Dumper; local $Data::Dumper::Useqq = 1; print Dumper \@var;
[thread]10452[/thread]

Performanceangaben unpack vs. regex



<< |< 1 2 >| >> 11 Einträge, 2 Seiten
mr-sansibar
 2007-09-24 14:17
#99914 #99914
User since
2006-04-13
90 Artikel
BenutzerIn
[default_avatar]
Hallo muss mich wieder bei Euch melden !
Und zwar geht es darum, dass ich gemerkt habe, dass das Verhalten von regex- und unpack hinsichtlich der Bearbeitung von Strings, unterschiedlich verhalten.#
dabei spielt die Stringlänge eine ganz besondere Rolle.
Durch ein Perl-Bechmarkmodul habe ich beide Verfahren auf ihre Schnelligkeit geprüft. Aber mir ist nicht einleuchtend, weshalb es zu diesem Ergebnissen kommt.

Unten ist eine Bechmark-Listing von unterschieldichen Stringlängen !!!

Stringlänge 250
_unpack2 140549/s -- -62%
_regex 368392/s 162% --

Stringlänge 500
Rate _unpack2 _regex
_unpack2 108668/s -- -52%
_regex 227950/s 110% --

Stringlänge 1000
Rate _unpack2 _regex
_unpack2 78118/s -- -38%
_regex 125237/s 60% --

Stringlänge 5000
Rate _regex _unpack2
_regex 16874/s -- -22%
_unpack2 21630/s 28% --

Stringlänge 10000
Rate _regex _unpack2
_regex 9437/s -- -17%
_unpack2 11366/s 20% --

Stringlänge 100000
Rate _regex _unpack2
_regex 863/s -- -28%
_unpack2 1191/s 38% --

Stringlänge 1000000
Rate _regex _unpack2
_regex 4.34/s -- -96%
_unpack2 116/s 2580% --


wie man hier sehen kann das bei einer hohen stringanzahl unpack effizienter läuft.
voran liegt dieses Phänomen, ich würde es sehr gerne wissen.
auf Literatur tips oder ähnliches würde ich mich ebenfalls sehr freuen !!!

für meinen fall würde sich die variante mit dem regex besser empfehlen, da ich meistens stringlängen zwischen 100 und 500 haben.

viele grüße
esskar
 2007-09-24 14:53
#99917 #99917
User since
2003-08-04
7321 Artikel
ModeratorIn

user image
wie hast du denn getestet?
mich wundert, dass regexp überhaupt schneller ist als unpack.
kannst du mal deine snippets posten?
mr-sansibar
 2007-09-24 15:01
#99918 #99918
User since
2006-04-13
90 Artikel
BenutzerIn
[default_avatar]
esskar+2007-09-24 12:53:21--
wie hast du denn getestet?
mich wundert, dass regexp überhaupt schneller ist als unpack.
kannst du mal deine snippets posten?



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
use strict;
use warnings;
use Benchmark;
 
my $line = 'x' x 250;
 
open my $frontend, '>>', '/dev/null' or die $!;
 
Benchmark::cmpthese(-1, {
    _regex => \&_regex,
    _unpack2 => \&_unpack2
 });
 
 sub _regex {
     my $tmp_line = $line;
     if( length $tmp_line < 4000 ){
         $tmp_line .= "\t" x 30;
     }
     else{
         $tmp_line =~ s/(.{4000})/$1\t/g;
     }
     print $frontend $tmp_line;
 }
 
 
 sub _unpack2 {
     my $tmp_line = $line;
     my $len = length($tmp_line);
     my $pos = 0;
     my $tab = 30;
     while ( my $s = unpack("x$pos A4000", $tmp_line) ) {
         $tab--;
         print $frontend "$s\t";
         $pos += 4000;
         last if $pos >= $len;
     }
     print $frontend "\t" x $tab;
     print $frontend "\n";
}
esskar
 2007-09-24 15:05
#99919 #99919
User since
2003-08-04
7321 Artikel
ModeratorIn

user image
ist dir mal in den sinn gekommen, dasss

Code: (dl )
1
2
3
4
if( length $tmp_line < 4000 ){
$tmp_line .= "\t" x 30;
}
else ...

die sache verbessert?
mr-sansibar
 2007-09-24 15:18
#99920 #99920
User since
2006-04-13
90 Artikel
BenutzerIn
[default_avatar]
esskar+2007-09-24 13:05:41--
ist dir mal in den sinn gekommen, dasss

Code: (dl )
1
2
3
4
if( length $tmp_line < 4000 ){
$tmp_line .= "\t" x 30;
}
else ...

die sache verbessert?


keine ahnung was du mit dieser aussage meinst !
renee
 2007-09-24 15:20
#99921 #99921
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Esskar meint, dass bei Stringlängen bis 4000 überhaupt kein Regulärer Ausdruck mit im Spiel ist! (Sondern nur einfache Stringkonkatenation)

Edit: Und ab einer Länge von 4000 (wo dann die RegEx eine Rolle spielen) "verändert" sich Dein Benchmark zu Gunsten von unpack.
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
bloonix
 2007-09-24 15:22
#99922 #99922
User since
2005-12-17
1615 Artikel
HausmeisterIn
[Homepage]
user image
Na esskar meint damit, dass bei einer Stringlänge < 4000 die Regex garnicht
angeschmissen wird, somit ist der Vergleich nicht korrekt!

Aber dein Problem kenn ich doch... dazu gab es doch mal einen Thread:

http://board.perl-community.de/thread/9934/startWi...

Dein Anliegen hättest du ruhig in diesen Thread schreiben können :-)
What is a good module? That's hard to say.
What is good code? That's also hard to say.
One man's Thing of Beauty is another's man's Evil Hack.
mr-sansibar
 2007-09-24 16:19
#99926 #99926
User since
2006-04-13
90 Artikel
BenutzerIn
[default_avatar]
so jetzt habe ich beiden diese Bedingung eingebaut, wegen der Chancengleichheit !
aber meine frage ist dadurch immer noch nicht beantwortet :-(

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
use strict;
use warnings;
use Benchmark;
 
my $line = 'x' x 100;
 
open my $frontend, '>>', '/dev/null' or die $!;
 
Benchmark::cmpthese(-1, {
    _regex => \&_regex,
   # _unpack1 => \&_unpack1,
    _unpack2 => \&_unpack2
 });
 
 sub _regex {
     my $tmp_line = $line;
     if( length $tmp_line < 4000 ){
        $tmp_line .= "\t" x 30;
    }
    else{
         $tmp_line =~ s/(.{4000})/$1\t/g;
     }
     print $frontend $tmp_line;
 }
 
  
 sub _unpack2 {
     my $tmp_line = $line;
     my $len = length($tmp_line);
     my $pos = 0;
     my $tab = 30;
     
     if( length $tmp_line < 4000 ){
        $tmp_line .= "\t" x 30;
    }
    else {
     while ( my $s = unpack("x$pos A4000", $tmp_line) ) {
         $tab--;
         print $frontend "$s\t";
         $pos += 4000;
         last if $pos >= $len;
     }
    }
     print $frontend "\t" x $tab;
     print $frontend "\n";
}


erst bei einer stringlänge >4000 werde beide verfahren deutlich !
renee
 2007-09-24 16:29
#99927 #99927
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Und wie sieht das Ergebnis nach der Änderung aus?
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
sid burn
 2007-09-24 21:09
#99940 #99940
User since
2006-03-29
1520 Artikel
BenutzerIn

user image
renee+2007-09-24 14:29:36--
Und wie sieht das Ergebnis nach der Änderung aus?

Wahrscheinlich gleich schnell, bzw eigentlich soltle die Regex in diesem Benchmark schneller sein. Wenn ich mich nicht verkucke dann wird in _regex und in _unpack2 niemals eine regex oder der unpack Befehl ausgeführt.

Bei beiden Subroutinen wird am anfang eine kopie von $line in $tmp_line erstellt. Danach wird überprüft $tmp_line < 4000 ist. Das ist es und dann wird an $tmp_line 30 x Tabs hinzugefügt. Die Subroutine beendet sich und $tmp_line wird gelöscht. Bei jede Funktionsaufruf passiert jetzt das selbe.

Allerdiengs werden im gegensatz zur _regex Methode in der _unpack2 Methode:
3 Variablen mehr definiert.
1 Funktionsaufruf mehr
1 print Befehl mehr.
1 string duplizieren mehr

ausgeführt. Wodurch die _unpack2 Funktion langsamer sein sollte.
Nicht mehr aktiv. Bei Kontakt: ICQ: 404181669 E-Mail: perl@david-raab.de
<< |< 1 2 >| >> 11 Einträge, 2 Seiten



View all threads created 2007-09-24 14:17.