summaryrefslogtreecommitdiff
path: root/deps/uv/test/benchmark-fs-stat.c
diff options
context:
space:
mode:
authorisaacs <i@izs.me>2012-06-22 07:44:40 -0700
committerisaacs <i@izs.me>2012-06-22 07:44:40 -0700
commit5565366a33e57436be08b00c14470ecafdf16632 (patch)
treeb6738c92c90ec38062ceb4e9a46ee20bd0485770 /deps/uv/test/benchmark-fs-stat.c
parenta1b274108fc7eb961c71eef3b61e5b332a9e187d (diff)
downloadandroid-node-v8-5565366a33e57436be08b00c14470ecafdf16632.tar.gz
android-node-v8-5565366a33e57436be08b00c14470ecafdf16632.tar.bz2
android-node-v8-5565366a33e57436be08b00c14470ecafdf16632.zip
uv: Upgrade to 171e2f71b9
Diffstat (limited to 'deps/uv/test/benchmark-fs-stat.c')
-rw-r--r--deps/uv/test/benchmark-fs-stat.c164
1 files changed, 164 insertions, 0 deletions
diff --git a/deps/uv/test/benchmark-fs-stat.c b/deps/uv/test/benchmark-fs-stat.c
new file mode 100644
index 0000000000..53aa60b14e
--- /dev/null
+++ b/deps/uv/test/benchmark-fs-stat.c
@@ -0,0 +1,164 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "task.h"
+#include "uv.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#define NUM_SYNC_REQS (10 * 1e5)
+#define NUM_ASYNC_REQS (1 * 1e5)
+#define MAX_CONCURRENT_REQS 32
+
+#define sync_stat(req, path) \
+ do { \
+ uv_fs_stat(uv_default_loop(), (req), (path), NULL); \
+ uv_fs_req_cleanup((req)); \
+ } \
+ while (0)
+
+struct async_req {
+ const char* path;
+ uv_fs_t fs_req;
+ int* count;
+};
+
+
+static const char* fmt(double d) {
+ uint64_t v;
+ char* p;
+
+ p = (char *) calloc(1, 32) + 31; /* leaks memory */
+ v = d;
+
+#if 0 /* works but we don't care about fractional precision */
+ if (d - v >= 0.01) {
+ *--p = '0' + (uint64_t) (d * 100) % 10;
+ *--p = '0' + (uint64_t) (d * 10) % 10;
+ *--p = '.';
+ }
+#endif
+
+ if (v == 0)
+ *--p = '0';
+
+ while (v) {
+ if (v) *--p = '0' + (v % 10), v /= 10;
+ if (v) *--p = '0' + (v % 10), v /= 10;
+ if (v) *--p = '0' + (v % 10), v /= 10;
+ if (v) *--p = ',';
+ }
+
+ return p;
+}
+
+
+static void warmup(const char* path) {
+ uv_fs_t reqs[MAX_CONCURRENT_REQS];
+ int i;
+
+ /* warm up the thread pool */
+ for (i = 0; i < ARRAY_SIZE(reqs); i++)
+ uv_fs_stat(uv_default_loop(), reqs + i, path, uv_fs_req_cleanup);
+
+ uv_run(uv_default_loop());
+
+ /* warm up the OS dirent cache */
+ for (i = 0; i < 16; i++)
+ sync_stat(reqs + 0, path);
+}
+
+
+static void sync_bench(const char* path) {
+ uint64_t before;
+ uint64_t after;
+ uv_fs_t req;
+ int i;
+
+ /* do the sync benchmark */
+ before = uv_hrtime();
+
+ for (i = 0; i < NUM_SYNC_REQS; i++)
+ sync_stat(&req, path);
+
+ after = uv_hrtime();
+
+ printf("%s stats (sync): %.2fs (%s/s)\n",
+ fmt(1.0 * NUM_SYNC_REQS),
+ (after - before) / 1e9,
+ fmt((1.0 * NUM_SYNC_REQS) / ((after - before) / 1e9)));
+ fflush(stdout);
+}
+
+
+static void stat_cb(uv_fs_t* fs_req) {
+ struct async_req* req = container_of(fs_req, struct async_req, fs_req);
+ uv_fs_req_cleanup(&req->fs_req);
+ if (*req->count == 0) return;
+ uv_fs_stat(uv_default_loop(), &req->fs_req, req->path, stat_cb);
+ (*req->count)--;
+}
+
+
+static void async_bench(const char* path) {
+ struct async_req reqs[MAX_CONCURRENT_REQS];
+ struct async_req* req;
+ uint64_t before;
+ uint64_t after;
+ int count;
+ int i;
+
+ for (i = 1; i <= MAX_CONCURRENT_REQS; i++) {
+ count = NUM_ASYNC_REQS;
+
+ for (req = reqs; req < reqs + i; req++) {
+ req->path = path;
+ req->count = &count;
+ uv_fs_stat(uv_default_loop(), &req->fs_req, req->path, stat_cb);
+ }
+
+ before = uv_hrtime();
+ uv_run(uv_default_loop());
+ after = uv_hrtime();
+
+ printf("%s stats (%d concurrent): %.2fs (%s/s)\n",
+ fmt(1.0 * NUM_ASYNC_REQS),
+ i,
+ (after - before) / 1e9,
+ fmt((1.0 * NUM_ASYNC_REQS) / ((after - before) / 1e9)));
+ fflush(stdout);
+ }
+}
+
+
+/* This benchmark aims to measure the overhead of doing I/O syscalls from
+ * the thread pool. The stat() syscall was chosen because its results are
+ * easy for the operating system to cache, taking the actual I/O overhead
+ * out of the equation.
+ */
+BENCHMARK_IMPL(fs_stat) {
+ const char path[] = ".";
+ warmup(path);
+ sync_bench(path);
+ async_bench(path);
+ return 0;
+}