From: Eric Wong <e@80x24.org>
To: spew@80x24.org
Subject: [PATCH] file.c: avoid on-stack stat buffer copy
Date: Fri, 24 Mar 2017 18:44:01 +0000 [thread overview]
Message-ID: <20170324184401.29511-1-e@80x24.org> (raw)
Optimize the successful case of File.stat, File.lstat, IO#stat,
File#lstat by avoiding copying of "struct stat" from the stack
to heap memory.
The exception case is slower, but exceptions ought to be rare
and not worth optimizing
* file.c (stat_wrap): new function
(stat_fail): ditto
(rb_file_s_stat): optimize for success, avoid on-stack "struct stat"
(rb_io_stat): ditto
(rb_file_s_lstat): ditto
(rb_file_lstat): ditto
---
file.c | 54 ++++++++++++++++++++++++++++++++++++++----------------
1 file changed, 38 insertions(+), 16 deletions(-)
diff --git a/file.c b/file.c
index c576c85c0a..2e13383f9c 100644
--- a/file.c
+++ b/file.c
@@ -429,6 +429,12 @@ get_stat(VALUE self)
return st;
}
+static VALUE
+stat_wrap(struct stat *st)
+{
+ return TypedData_Wrap_Struct(rb_cStat, &stat_data_type, st);
+}
+
static struct timespec stat_mtimespec(struct stat *st);
/*
@@ -1084,6 +1090,16 @@ call_w32_io_info(VALUE arg)
}
#endif
+static void
+stat_fail(struct stat *st, VALUE fname)
+{
+ int err = errno;
+
+ xfree(st);
+ errno = err;
+ rb_sys_fail_path(fname);
+}
+
/*
* call-seq:
* File.stat(file_name) -> stat
@@ -1098,13 +1114,14 @@ call_w32_io_info(VALUE arg)
static VALUE
rb_file_s_stat(VALUE klass, VALUE fname)
{
- struct stat st;
+ struct stat *st;
FilePathValue(fname);
- if (rb_stat(fname, &st) < 0) {
- rb_sys_fail_path(fname);
+ st = ALLOC(struct stat);
+ if (rb_stat(fname, st) < 0) {
+ stat_fail(st, fname);
}
- return rb_stat_new(&st);
+ return stat_wrap(st);
}
/*
@@ -1126,13 +1143,14 @@ static VALUE
rb_io_stat(VALUE obj)
{
rb_io_t *fptr;
- struct stat st;
+ struct stat *st;
GetOpenFile(obj, fptr);
- if (fstat(fptr->fd, &st) == -1) {
- rb_sys_fail_path(fptr->pathv);
+ st = ALLOC(struct stat);
+ if (fstat(fptr->fd, st) == -1) {
+ stat_fail(st, fptr->pathv);
}
- return rb_stat_new(&st);
+ return stat_wrap(st);
}
/*
@@ -1153,14 +1171,17 @@ static VALUE
rb_file_s_lstat(VALUE klass, VALUE fname)
{
#ifdef HAVE_LSTAT
- struct stat st;
+ struct stat *st;
+ const char *cstr;
FilePathValue(fname);
fname = rb_str_encode_ospath(fname);
- if (lstat(StringValueCStr(fname), &st) == -1) {
- rb_sys_fail_path(fname);
+ cstr = StringValueCStr(fname);
+ st = ALLOC(struct stat);
+ if (lstat(cstr, st) == -1) {
+ stat_fail(st, fname);
}
- return rb_stat_new(&st);
+ return stat_wrap(st);
#else
return rb_file_s_stat(klass, fname);
#endif
@@ -1185,16 +1206,17 @@ rb_file_lstat(VALUE obj)
{
#ifdef HAVE_LSTAT
rb_io_t *fptr;
- struct stat st;
+ struct stat *st;
VALUE path;
GetOpenFile(obj, fptr);
if (NIL_P(fptr->pathv)) return Qnil;
path = rb_str_encode_ospath(fptr->pathv);
- if (lstat(RSTRING_PTR(path), &st) == -1) {
- rb_sys_fail_path(fptr->pathv);
+ st = ALLOC(struct stat);
+ if (lstat(RSTRING_PTR(path), st) == -1) {
+ stat_fail(st, fptr->pathv);
}
- return rb_stat_new(&st);
+ return stat_wrap(st);
#else
return rb_io_stat(obj);
#endif
--
EW
reply other threads:[~2017-03-24 18:44 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170324184401.29511-1-e@80x24.org \
--to=e@80x24.org \
--cc=spew@80x24.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).