1
1

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>
Этот коммит содержится в:
Devin Hussey 2018-06-08 12:38:19 -04:00 коммит произвёл Benno Schulenberg
родитель 3bac3c4c78
Коммит b2ff574678

Просмотреть файл

@ -760,8 +760,12 @@ void read_file(FILE *f, int fd, const char *filename, bool undoable)
topline = make_new_node(NULL);
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. */
while ((input_int = getc(f)) != EOF) {
while ((input_int = getc_unlocked(f)) != EOF) {
input = (char)input_int;
/* 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
}
/* We are done with the file, unlock it. */
funlockfile(f);
/* Perhaps this could use some better handling. */
if (ferror(f))
nperror(filename);