nano

nano with my custom patches
git clone git://bsandro.tech/nano
Log | Files | Refs | README | LICENSE

commit b2ff57467874e1c0cfad146a76acf0d9f3a0084c
parent 3bac3c4c78a3eea5384a864a16579cfa3ad7039a
Author: Devin Hussey <husseydevin@gmail.com>
Date:   Fri,  8 Jun 2018 12:38:19 -0400

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>

Diffstat:
Msrc/files.c | 9++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/src/files.c b/src/files.c @@ -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);