files: speed up reading by using getc_unlocked() instead of getc()
Unlike glibc, which in getc() locks the file only when it is needed, FreeBSD and Bionic libc will always lock the file, causing a massive slowdown, as the system has to create and destroy a mutex each time getc() is called. Avoid that massive overhead by locking the file before starting to read and unlocking it after reading is complete, and using getc_unlocked() to read each byte. This makes reading on FreeBSD/macOS and Android anywhere from 2 to 6 times faster, and on glibc roughly seventy percent faster. This partially addresses https://savannah.gnu.org/bugs/?50406. Signed-off-by: Devin Hussey <husseydevin@gmail.com>
Этот коммит содержится в:
родитель
3bac3c4c78
Коммит
b2ff574678
@ -760,8 +760,12 @@ void read_file(FILE *f, int fd, const char *filename, bool undoable)
|
|||||||
topline = make_new_node(NULL);
|
topline = make_new_node(NULL);
|
||||||
bottomline = topline;
|
bottomline = topline;
|
||||||
|
|
||||||
|
/* Lock the file before starting to read it, to avoid the overhead
|
||||||
|
* of locking it for each single byte that we read from it. */
|
||||||
|
flockfile(f);
|
||||||
|
|
||||||
/* Read the entire file into the new buffer. */
|
/* Read the entire file into the new buffer. */
|
||||||
while ((input_int = getc(f)) != EOF) {
|
while ((input_int = getc_unlocked(f)) != EOF) {
|
||||||
input = (char)input_int;
|
input = (char)input_int;
|
||||||
|
|
||||||
/* If it's a *nix file ("\n") or a DOS file ("\r\n"), and file
|
/* If it's a *nix file ("\n") or a DOS file ("\r\n"), and file
|
||||||
@ -828,6 +832,9 @@ void read_file(FILE *f, int fd, const char *filename, bool undoable)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* We are done with the file, unlock it. */
|
||||||
|
funlockfile(f);
|
||||||
|
|
||||||
/* Perhaps this could use some better handling. */
|
/* Perhaps this could use some better handling. */
|
||||||
if (ferror(f))
|
if (ferror(f))
|
||||||
nperror(filename);
|
nperror(filename);
|
||||||
|
Загрузка…
Ссылка в новой задаче
Block a user