2016-04-30 11 views
0


Ich nenne einen Systemaufruf wie write() in C, auf der anderen Seite ich write() mit dlsym() auf diese Weise aufrufen:Systemaufruf oder dlsym? Welcher Weg ist schneller?

ssize_t original_write(int fd, const void *buf, size_t count) 
{ 
    typedef ssize_t (*orig_write_type)(int, const void *, size_t); 
    static orig_write_type orig_write; 
    if (!orig_write) 
     orig_write = (orig_write_type) dlsym(RTLD_NEXT, "write"); 
    ssize_t ret = orig_write(fd, buf, count); 
    return ret; 
} 

Ich bin neugierig, welche Art und Weise schneller ist? Wenn ich write() rufe, ruft es auch dlsym() implizit auf, um seine Adresse zu erhalten? Bitte korrigieren Sie mich. Vielen Dank für Ihre Zeit.

+0

Der Compiler wird wahrscheinlich beide in den gleichen Code umwandeln. – Leandros

+1

Was ist schneller? Sie können das selbst messen ... –

+2

C sagt nichts über 'dlsym()' - es gehört nicht zu den von C definierten Standardbibliotheksfunktionen. Außerdem wäre ich sehr überrascht, irgendeine Implementierung mit 'dlsym()' zu finden Implementieren von Funktionsaufrufen in dynamische Bibliotheken. Systeme mit dynamischen Bibliotheken haben normalerweise irgendeine Form von dynamischem Linker, die es unnötig macht. Aber insgesamt, * warum in der Welt würden Sie so ein hässliches Durcheinander zu Ihrem Programm * hinzufügen wollen? –

Antwort

1

Wenn es um Fragen geht, die schneller sind, verwenden Sie einen Profiler und geben Sie den Code selbst ein.

Das heißt, ein statischer Anruf ist immer schneller als ein dynamischer Anruf für den ersten Anruf. Sobald die Funktion dynamisch geladen wurde, sollten die beiden bei fast die gleiche Geschwindigkeit laufen. Der gezeigte dynamische Ansatz verwendet einige zusätzliche Anweisungen, um die Variable static zu überprüfen, sodass der dynamische Aufruf nicht so schnell wie der statische Aufruf genau ist.

Sie können dies vermeiden, indem Sie die Variable static insgesamt loswerden. Schreiben Sie eine Stub-Funktion und deklarieren Sie eine Funktionszeigervariable, die auf diesen Stub zeigt. Lassen Sie den Stub die reale Funktion laden, aktualisieren Sie die Variable, um auf sie zu zeigen, und rufen Sie sie dann auf. Dann können Sie den Funktionszeiger für alle Ihre Anrufe verwenden. Das erste Mal wird den Stub aufrufen, jedes weitere Mal wird die reale Funktion direkt aufrufen.

Verwandte Themen