Laufzeiten von evals...

Begonnen von erwin, 08 Dezember 2022, 11:18:45

Vorheriges Thema - Nächstes Thema

erwin

ich wollte mal checken, was ein eval an Laufzeit kostet, vs precompiled oder ohne eval.
Vielleicht ist mein Beispiel zu trivial oder ganz falsch - deshalb hier zur Diskussion:
#!/usr/bin/perl
# testing speed of eval

use strict;
use warnings;
use Time::HiRes qw(gettimeofday time);

my $j = 0;
my $ts;

# precompile and check for error
my $cval = eval(q{sub {my $foo = shift;return $foo++;} }); ## no critic 'ProhibitStringyEval'
if(!$cval || $@) {
print "evals error $@ \n";
exit;
}

# without eval
sub addone {
my $foo = shift;
return $foo++;
}

# run eval precompiled
$ts = time;
for my $i (0..100000) {
        $j = $cval->($i);
}
my $dur = time - $ts;
print " Peval_res=   $j dur= $dur \n";

# run evals
$ts = time;
for my $i (0..100000) {
        $j = eval ( $i); ## no critic 'ProhibitStringyEval'
}
my $dur1 = time - $ts;
print "  eval_res=   $j dur= $dur1 \n";
print "Gain=  " . $dur1/$dur . " \n";

# run w.o. eval
$ts = time;
for my $i (0..100000) {
        $j = addone($i);
}
my $dur2 = time - $ts;
print "NOeval_res=   $j dur= $dur2 \n";


# run w.o. sub & eval
$ts = time;
for my $i (0..100000) {
        $j = $i++;
}
my $dur3 = time - $ts;
print " NOsub_res=   $j dur= $dur3 \n";

exit;


Output:
./evaltest.pl
Peval_res=   100000 dur= 0.59893798828125
  eval_res=   100000 dur= 9.32247710227966
Gain=  15.5650122127535
NOeval_res=   100000 dur= 0.576098918914795
NOsub_res=   100000 dur= 0.150755167007446


soll heissen :

  • Ein precompiled eval ist um den Faktor 15 schneller als ein inline eval!
  • Ein sub Aufruf OHNE eval ist nicht viel schneller als das precompiled eval
  • der inline code (ohne sub) ist nochmal um den Faktor 4 scheller - das zeigt in wesentlichen den overhead des sub-calls...
Fragen dazu:
ist das setup valid?
geht es etwas eleganter ? / kürzerer code ?
Die Anforderung ist, dass man zur Laufzeit variaben übergeben kann/muss.
?
l.g. erwin
FHEM aktuell auf RaspberryPI Mdl 1-4
Maintainer: 00_KNXIO.pm 10_KNX.pm
User: CUNO2 (868 SLOWRF) - HMS100xx, FS20, FHT, 1-Wire  - 2401(iButton), 18x20, 2406, 2413 (AVR), 2450,..,MQTT2, KNX, SONOFF, mySENSORS,....
Hardware:  Busware ROT, Weinzierl IP731, 1-Wire GW,...

rudolfkoenig

Ich glaube die Zahlen sind korrekt.
Oder auch: das Eval Overhead enstpricht ca 15 shift+inkrement Operationen, in absoluten Zahlen 0.1ms.

Damian

Du musst aber einen langsamen Rechner haben. Mein alter raspi 2 ist 8 mal schneller :)

Wenn wir schon bei effizienter Programmierung sind:

for (my $i=0;$i<=100000;$i++)

ist ca. doppelt so schnell, wie

for my $i (0..100000)




Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

erwin

Hi Damian,
re. 8mal schneller: Interessant... Bei mir auch ein alter PI-2 Mdl.B. - allerdings mit Jessie - Perl Version 5.20 - möglicherweise daher die Unterschiede...
Den verwende ich als Test/Development environment, falls dort funktioniert, teste ich mit buster u. bullseye...- erst dann gehts ins SVN.

re. for loops: erstaunlich! - wusste ich auch noch nicht....
Ich hatte mich in meiner perl "lern-Kurve" oft am Stil von Rudi orientiert...
PBP meint allerdings, man sollte "C-Style" for loops vermeiden, die Begründung ist m.M. etwas "dünn"  (readability/mainainability...), der Author gibt allerdings zu, dass "C-style" for loops üblicherweise schneller sind....
FHEM aktuell auf RaspberryPI Mdl 1-4
Maintainer: 00_KNXIO.pm 10_KNX.pm
User: CUNO2 (868 SLOWRF) - HMS100xx, FS20, FHT, 1-Wire  - 2401(iButton), 18x20, 2406, 2413 (AVR), 2450,..,MQTT2, KNX, SONOFF, mySENSORS,....
Hardware:  Busware ROT, Weinzierl IP731, 1-Wire GW,...