Ich habe einen Dateideskriptor fd , einen Offset und eine Länge, und ich muss länge NULL
bytes von offset schreiben die Datei, die von fd beschrieben wird (Anmerkung: sie tritt nie am Ende der Datei auf).
Gibt es einen effizienten Weg dies zu tun, abgesehen davon, einen Puffer zu benutzen, der mit NULL
s gefüllt ist und ihn wiederholt in eine Schleife schreibt? Die Reihenfolge von NULL
s kann bis zu 16Mo gehen und ich verwende derzeit einen Puffer der Größe 512 (= ~ 30k Aufrufe an write(2)
).
Sie könnten mmap
in der Datei mit dem gewünschten Offset und Mapping in genau der erforderlichen Größe versuchen und dann einfach memset
aufrufen.
EDIT: Basierend auf dem Code von @jthill, hier ist ein einfaches Beispiel, das zeigt, wie man einen Vergleich durchführt.
%Vor% ANMERKUNGEN: mmap
mag es nicht, wenn der angegebene Offset nicht ausgerichtet ist (normalerweise auf einer Seitengrenze), also ist es möglicherweise schöner, wenn Sie die Länge + Offset zuordnen und einfach vom Offset (oder alternativ, wenn Sie einen schön ausgerichteten Offset garantieren können, wird dies auch funktionieren ..)
Wie Sie sehen können, sind die Unterschiede zwischen den beiden Operationen lseek
( map + seek
) und dann write
( memset
). Ich denke, das ist ein fairer Vergleich (wenn jemand etwas reparieren will, fühlen Sie sich frei.)
Ich benutze auch MAP_SHARED
und nicht MAP_PRIVATE
, es gibt einen signifikanten Unterschied zwischen den beiden, letzteres ist Copy-on-Write, was viel langsamer sein kann!
Auf meinem nicht so mächtigen System bekomme ich:
%Vor% Ich denke, dass mmap
+ memset
schneller ist?
Wenn Sie Linux ausführen und das Dateisystem Sparse-Dateien unterstützt, könnten Sie versuchen, ein Loch in Ihre Datei zu schlagen, indem Sie fallocate(2)
mit dem FALLOC_FL_PUNCH_HOLE
-Flag verwenden. Ich würde erwarten, dass das schnell ist, obwohl ich es nicht getestet habe.
Unter Linux können Sie splice(2)
verwenden, um Daten von /dev/zero
zu kopieren.
Das ist ziemlich effizient, da die meiste Arbeit innerhalb des Kernels erledigt wird.
Andere Betriebssysteme bieten möglicherweise eine ähnliche Möglichkeit (d. h. sendfile
).
update !
Ich habe fallocate(2)
vergessen, das Löcher in der Mitte einer Datei ausstanzen kann.
Von unten, 16M von I / O, die schlecht einmal gemacht werden, ist & gt; 20ms. Das grenzt an sich selbst an.
Mitnehmen:
Offsets entweder im Speicher oder auf der Platte sind nicht so wichtig, calloc
'ing was auch immer gut tun sollte (Sie könnten es versuchen).
Tags und Links c performance system-calls