Ich habe vergessen, die Leistung in dem Artikel zu bewerten, den ich zuvor geschrieben habe: "Ich habe versucht, das schnellste FizzBuzz anzustreben". Bist du dumm? Aus diesem Grund haben wir die Leistung des fehlenden Programms bewertet.
Das letzte FizzBuzz-Programm, das ich erstellt habe
$ time -p ./fizzbuzz >/dev/null
real 0.00
user 0.00
sys 0.00
$
Dies ist nicht sinnvoll, da die Ausführungszeit des Programms zu kurz ist, um mit dem Befehl time gemessen zu werden. Mit ein wenig Einfallsreichtum
$ time -p (for i in `seq 1 10000`; do ./fizzbuzz; done) >/dev/null
real 6.76
user 4.55
sys 4.41
Eine Methode zum mehrfachen Ausführen und Teilen der Ausführungszeit durch die Anzahl der Ausführungen kann in Betracht gezogen werden. Diese Methode wird jedoch nicht angewendet, da die Wiederholung durch die Shell teurer zu sein scheint als die Ausführungszeit des Programms. Dieses Mal habe ich beschlossen, ein kurzes Programm zu erstellen, das wiederholt dasselbe Programm ausführt und es verwendet.
repeat.c
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <stdbool.h>
#include <unistd.h>
#include <errno.h>
#include <spawn.h>
#include <sys/wait.h>
int main(int argc, char* argv[])
{
int opt;
int n = 1;
bool f = false;
int fd = -1;
opterr = 0;
while ((opt = getopt(argc, argv, "hfn:")) != -1) {
switch (opt) {
case 'h':
default:
fprintf(stderr, "Usage: repeat [options]... command\n");
exit(EXIT_FAILURE);
break;
case 'f':
f = true;
break;
case 'n':
n = atoi(optarg);
break;
}
}
if (f) {
fd = open("/proc/sys/vm/drop_caches", O_WRONLY);
}
for (int i = 1; i <= n; i++) {
if (f && fd >= 0) {
while (write(fd, "1", 1) == -1 && errno == EINTR) {
;
}
}
pid_t pid;
posix_spawn(&pid, argv[optind], NULL, NULL, &argv[optind], NULL);
int status;
wait(&status);
if (status) {
fprintf(stderr, "pid %d: %d\n", pid, status);
exit(status);
}
}
if (f && fd >= 0) {
close(fd);
}
}
Dies
$ gcc -Wall -Wextra -O2 repeat.c -o repeat
Kompilieren als
python
$ time -p ./repeat -n 10000 ./fizzbuzz >/dev/null
real 1.84
user 1.44
sys 0.48
$
Benutzen als. Die Befehlszeilenoption \ -n Wert gibt an, wie oft das Programm wiederholt ausgeführt wird, und die vom Zeitbefehl ausgegebene Anzahl wird durch die Anzahl der Ausführungen geteilt, um die Ausführungszeit pro Ausführung zu erhalten. Sobald das Programm von der Festplatte gelesen wurde, wird sein Inhalt im Seitencache registriert, und es wird die Festplatte bei wiederholter Ausführung nicht mehr lesen. Da wir auch die Last des Lesens des Programms von der Festplatte auswerten möchten, haben wir eine Funktion bereitgestellt, um das Programm aus dem Zustand auszuführen, in dem der Seitencache gelöscht wird, indem die Befehlszeilenoption \
-f 'angegeben wird. Der Seitencache wird durch Schreiben von 1 in / proc / sys / vm / drop_caches geleert. Administratorrechte sind erforderlich. Daher muss sudo zusammen verwendet werden.
$ sudo time -p ./repeat -n 10000 -f ./fizzbuzz >/dev/null
real 85.90
user 3.26
sys 78.85
$
Wie im vorherigen Beispiel wird die Ausgabenummer durch die Anzahl der Wiederholungen geteilt, um die Ausführungszeit einschließlich der Programmladezeit zu erhalten.
Kein Cache löschen (* Der numerische Wert ist die Zeit (Sekunden), die 10.000 Mal ausgeführt wurde.)
Dynamische Link-Version in C-Sprache | Statische Link-Version in C-Sprache | Assembler-Version | |
---|---|---|---|
real | 4.55 | 2.99 | 1.82 |
user | 3.65 | 2.37 | 1.43 |
sys | 0.91 | 0.69 | 0.47 |
Es gibt Bargeld (* wie oben)
Dynamische Link-Version in C-Sprache | Statische Link-Version in C-Sprache | Assembler-Version | |
---|---|---|---|
real | 121.74 | 142.39 | 85.90 |
user | 8.15 | 9.46 | 3.26 |
sys | 93.45 | 95.96 | 78.85 |
Größe der Ausführungsdatei (* Einheit ist Bytes)
Dynamische Link-Version in C-Sprache | Statische Link-Version in C-Sprache | Assembler-Version |
---|---|---|
6112 | 714736 | 808 |
Das Ende.
Recommended Posts