[Python-checkins] peps: PEP 433: add test scripts; performances results on Linux 3.6
victor.stinner
python-checkins at python.org
Mon Jan 28 16:17:29 CET 2013
http://hg.python.org/peps/rev/d269feb2c809
changeset: 4694:d269feb2c809
user: Victor Stinner <victor.stinner at gmail.com>
date: Sun Jan 27 13:35:21 2013 +0100
summary:
PEP 433: add test scripts; performances results on Linux 3.6
files:
pep-0433.txt | 15 ++++++--
pep-0433/bench_cloexec.py | 45 +++++++++++++++++++++++++++
pep-0433/openbsd_bug.py | 32 +++++++++++++++++++
3 files changed, 88 insertions(+), 4 deletions(-)
diff --git a/pep-0433.txt b/pep-0433.txt
--- a/pep-0433.txt
+++ b/pep-0433.txt
@@ -143,9 +143,8 @@
.. note::
OpenBSD older 5.2 does not close the file descriptor with
close-on-exec flag set if ``fork()`` is used before ``exec()``, but
- it works correctly if ``exec()`` is called without ``fork()``.
-
-XXX recheck this OpenBSD bug using a C program. XXX
+ it works correctly if ``exec()`` is called without ``fork()``. Try
+ `openbsd_bug.py <http://hg.python.org/peps/file/tip/pep-0433/openbsd_bug.py>`_.
Scope
@@ -446,7 +445,15 @@
* ``fcntl(fd, F_SETFD, flags)``: two addition system calls per file
descriptor, one to get old flags and one to set new flags
-XXX Benchmark the overhead for these 4 methods. XXX
+On Linux, setting the close-on-flag has a low overhead on performances.
+Results of
+`bench_cloexec.py <http://hg.python.org/peps/file/tip/pep-0433/bench_cloexec.py>`_
+on Linux 3.6:
+
+ * close-on-flag not set: 7.8 us
+ * ``O_CLOEXEC``: 1% slower (7.9 us)
+ * ``ioctl()``: 3% slower (8.0 us)
+ * ``fcntl()``: 3% slower (8.0 us)
Implementation
diff --git a/pep-0433/bench_cloexec.py b/pep-0433/bench_cloexec.py
new file mode 100644
--- /dev/null
+++ b/pep-0433/bench_cloexec.py
@@ -0,0 +1,45 @@
+"""
+Linux 3.6, O_CLOEXEC:
+
+open(cloexec=False) + close(): 7.76 us per call
+open(cloexec=True) + close(): 7.87 us per call
+
+=> 1% slower
+
+Linux 3.6, ioctl(FIOCLEX):
+
+open(cloexec=False) + close(): 7.77 us per call
+open(cloexec=True) + close(): 8.02 us per call
+
+=> 3% slower
+
+Linux 3.6, fnctl(F_GETFD) + fnctl(F_SETFD):
+
+open(cloexec=False) + close(): 7.77 us per call
+open(cloexec=True) + close(): 8.01 us per call
+
+=> 3% slower
+"""
+import os, time
+
+name = __file__
+LOOPS = 10**5
+RUNS = 5
+
+for cloexec in (False, True):
+ best = None
+ for run in range(RUNS):
+ print("cloexec", cloexec, "run", run)
+ time.sleep(1)
+ start = time.perf_counter()
+ for loops in range(LOOPS):
+ fd = os.open(name, os.O_RDONLY, cloexec=cloexec)
+ os.close(fd)
+ dt = time.perf_counter() - start
+ if best is not None:
+ best = min(best, dt)
+ else:
+ best = dt
+
+ seconds = best / LOOPS
+ print("open(cloexec=%s) + close(): %.2f us per call" % (cloexec, seconds * 1e6))
diff --git a/pep-0433/openbsd_bug.py b/pep-0433/openbsd_bug.py
new file mode 100644
--- /dev/null
+++ b/pep-0433/openbsd_bug.py
@@ -0,0 +1,32 @@
+# Script testing an OpenBSD bug
+#
+# The script fails with "OS BUG!!!" with OpenBSD older than 5.2.
+# It works on any version using USE_FORK = False.
+USE_FORK = True
+
+import fcntl, os, sys
+
+fd = os.open("/etc/passwd", os.O_RDONLY)
+flags = fcntl.fcntl(fd, fcntl.F_GETFD)
+flags |= fcntl.FD_CLOEXEC
+fcntl.fcntl(fd, fcntl.F_SETFD, flags)
+
+code = """
+import os, sys
+fd = int(sys.argv[1])
+try:
+ os.fstat(fd)
+except OSError:
+ print("fd %s closed by exec (FD_CLOEXEC works)" % fd)
+else:
+ print("fd %s not closed by exec: FD_CLOEXEC doesn't work, OS BUG!!!" % fd)
+"""
+
+args = [sys.executable, '-c', code, str(fd)]
+if USE_FORK:
+ pid = os.fork()
+ if pid:
+ os.waitpid(pid, 0)
+ sys.exit(0)
+
+os.execv(args[0], args)
--
Repository URL: http://hg.python.org/peps
More information about the Python-checkins
mailing list