]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
A couple of compression microbenchmarks
authorTony Finch <fanf@isc.org>
Sat, 25 Jun 2022 14:29:54 +0000 (15:29 +0100)
committerOndřej Surý <ondrej@isc.org>
Mon, 17 Oct 2022 06:45:44 +0000 (08:45 +0200)
The `render` benchmark loads some binary DNS message dumps and
repeatedly passes them to `dns_message_render`.

The `compress` benchmark loads a list of domain names and packs them
into 4KiB chunks using `dns_name_towire`.

tests/bench/.gitignore
tests/bench/Makefile.am
tests/bench/compress.c [new file with mode: 0644]
tests/bench/render.c [new file with mode: 0644]

index fb6b5a462aff36b2c064282ef472c47d9fca3716..c7dfdd134fee2596e469421df4f54a1364b72395 100644 (file)
@@ -1,2 +1,4 @@
-ascii
-siphash
+/ascii
+/compress
+/render
+/siphash
index c53e6ea51d59e913a6a37a7f5c6d9c3eaa8c294d..ecdc961518bca74bf9ea1a99575315d2660351ff 100644 (file)
@@ -1,11 +1,15 @@
 include $(top_srcdir)/Makefile.top
 
 AM_CPPFLAGS +=                 \
-       $(LIBISC_CFLAGS)
+       $(LIBISC_CFLAGS)        \
+       $(LIBDNS_CFLAGS)
 
 LDADD +=                       \
-       $(LIBISC_LIBS)
+       $(LIBISC_LIBS)          \
+       $(LIBDNS_LIBS)
 
 noinst_PROGRAMS =              \
        ascii                   \
+       compress                \
+       render                  \
        siphash
diff --git a/tests/bench/compress.c b/tests/bench/compress.c
new file mode 100644 (file)
index 0000000..087b02d
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * SPDX-License-Identifier: MPL-2.0
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, you can obtain one at https://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+#include <err.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <isc/buffer.h>
+#include <isc/mem.h>
+#include <isc/result.h>
+#include <isc/time.h>
+#include <isc/util.h>
+
+#include <dns/compress.h>
+#include <dns/fixedname.h>
+#include <dns/name.h>
+
+static void
+CHECKRESULT(isc_result_t result, const char *msg) {
+       if (result != ISC_R_SUCCESS) {
+               printf("%s: %s\n", msg, isc_result_totext(result));
+               exit(1);
+       }
+}
+
+int
+main(void) {
+       isc_result_t result;
+       isc_buffer_t buf;
+
+       isc_mem_t *mctx = NULL;
+       isc_mem_create(&mctx);
+
+       static dns_fixedname_t fixedname[65536];
+       unsigned int count = 0;
+
+       char *line = NULL;
+       size_t linecap = 0;
+       ssize_t linelen;
+       while ((linelen = getline(&line, &linecap, stdin)) > 0) {
+               if (line[linelen - 1] == '\n') {
+                       line[--linelen] = '\0';
+               }
+               isc_buffer_init(&buf, line, linelen);
+               isc_buffer_add(&buf, linelen);
+
+               if (count == ARRAY_SIZE(fixedname)) {
+                       errx(1, "too many names");
+               }
+               dns_name_t *name = dns_fixedname_initname(&fixedname[count++]);
+               result = dns_name_fromtext(name, &buf, dns_rootname, 0, NULL);
+               CHECKRESULT(result, line);
+       }
+
+       unsigned int repeat = 100;
+
+       isc_time_t start;
+       isc_time_now_hires(&start);
+
+       for (unsigned int n = 0; n < repeat; n++) {
+               static uint8_t wire[4 * 1024];
+               dns_compress_t cctx;
+
+               isc_buffer_init(&buf, wire, sizeof(wire));
+               dns_compress_init(&cctx, mctx, 0);
+
+               for (unsigned int i = 0; i < count; i++) {
+                       dns_name_t *name = dns_fixedname_name(&fixedname[i]);
+                       result = dns_name_towire(name, &cctx, &buf);
+                       if (result == ISC_R_NOSPACE) {
+                               dns_compress_invalidate(&cctx);
+                               dns_compress_init(&cctx, mctx, 0);
+                               isc_buffer_init(&buf, wire, sizeof(wire));
+                       } else {
+                               CHECKRESULT(result, "dns_name_towire");
+                       }
+               }
+               dns_compress_invalidate(&cctx);
+       }
+
+       isc_time_t finish;
+       isc_time_now_hires(&finish);
+
+       uint64_t microseconds = isc_time_microdiff(&finish, &start);
+       printf("time %f / %u\n", (double)microseconds / 1000000.0, repeat);
+
+       printf("names %u\n", count);
+
+       isc_mem_destroy(&mctx);
+
+       return (0);
+}
diff --git a/tests/bench/render.c b/tests/bench/render.c
new file mode 100644 (file)
index 0000000..afee5c7
--- /dev/null
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * SPDX-License-Identifier: MPL-2.0
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, you can obtain one at https://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <isc/buffer.h>
+#include <isc/mem.h>
+#include <isc/result.h>
+#include <isc/time.h>
+
+#include <dns/message.h>
+
+static void
+CHECKRESULT(isc_result_t result, const char *msg) {
+       if (result != ISC_R_SUCCESS) {
+               printf("%s: %s\n", msg, isc_result_totext(result));
+               exit(1);
+       }
+}
+
+int
+main(int argc, char *argv[]) {
+       isc_result_t result;
+       ssize_t r;
+
+       isc_mem_t *mctx = NULL;
+       isc_mem_create(&mctx);
+
+       dns_message_t **message;
+       message = isc_mem_allocate(mctx, argc * sizeof(*message));
+
+       for (int i = 1; i < argc; i++) {
+               const char *filename = argv[i];
+
+               int fd = open(filename, O_RDONLY);
+               if (fd < 0)
+                       err(1, "open(%s)", filename);
+
+               isc_buffer_t *filebuf = NULL;
+               isc_buffer_allocate(mctx, &filebuf, 64 * 1024);
+
+               struct stat st;
+               r = fstat(fd, &st);
+               if (r < 0)
+                       err(1, "stat(%s)", filename);
+               if (st.st_size > isc_buffer_availablelength(filebuf))
+                       errx(1, "%s is too large", filename);
+               unsigned int filelen = (unsigned int)st.st_size;
+
+               isc_buffer_reserve(&filebuf, filelen);
+               r = read(fd, isc_buffer_base(filebuf), filelen);
+               if (r < 0)
+                       err(1, "read(%s)", filename);
+               if (st.st_size > r)
+                       errx(1, "read(%s) truncated", filename);
+               isc_buffer_add(filebuf, filelen);
+               close(fd);
+
+               message[i] = NULL;
+               dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &message[i]);
+
+               result = dns_message_parse(message[i], filebuf,
+                                          DNS_MESSAGEPARSE_PRESERVEORDER);
+               CHECKRESULT(result, "dns_message_parse()");
+               isc_buffer_free(&filebuf);
+
+               continue;
+
+               isc_buffer_t *printbuf = NULL;
+               isc_buffer_allocate(mctx, &printbuf, 1024 * 1024);
+
+               result = dns_message_totext(message[i], &dns_master_style_debug,
+                                           0, printbuf);
+               CHECKRESULT(result, "dns_message_totext()");
+
+               r = write(1, isc_buffer_base(printbuf),
+                         isc_buffer_usedlength(printbuf));
+               if (r < 0)
+                       err(1, "write(%s)", filename);
+               isc_buffer_free(&printbuf);
+       }
+
+       isc_time_t start;
+       isc_time_now_hires(&start);
+
+       unsigned int count = 0;
+       int repeat = 100;
+       for (int n = 0; n < repeat; n++) {
+               for (int i = 1; i < argc; i++) {
+                       isc_buffer_t *wirebuf = NULL;
+                       isc_buffer_allocate(mctx, &wirebuf, 64 * 1024);
+
+                       /* hacks! see wire_test.c */
+                       message[i]->from_to_wire = DNS_MESSAGE_INTENTRENDER;
+                       for (int s = 0; s < DNS_SECTION_MAX; s++) {
+                               message[i]->counts[s] = 0;
+                       }
+
+                       dns_compress_t cctx;
+                       dns_compress_init(&cctx, mctx, DNS_COMPRESS_LARGE);
+
+                       result = dns_message_renderbegin(message[i], &cctx,
+                                                        wirebuf);
+                       CHECKRESULT(result, "dns_message_renderbegin()");
+                       result = dns_message_rendersection(
+                               message[i], DNS_SECTION_QUESTION, 0);
+                       CHECKRESULT(result,
+                                   "dns_message_rendersection(QUESTION)");
+                       result = dns_message_rendersection(
+                               message[i], DNS_SECTION_ANSWER, 0);
+                       CHECKRESULT(result,
+                                   "dns_message_rendersection(ANSWER)");
+                       result = dns_message_rendersection(
+                               message[i], DNS_SECTION_AUTHORITY, 0);
+                       CHECKRESULT(result,
+                                   "dns_message_rendersection(AUTHORITY)");
+                       result = dns_message_rendersection(
+                               message[i], DNS_SECTION_ADDITIONAL, 0);
+                       CHECKRESULT(result,
+                                   "dns_message_rendersection(ADDITIONAL)");
+                       if (count < cctx.count)
+                               count = cctx.count;
+
+                       dns_message_renderend(message[i]);
+
+                       dns_compress_invalidate(&cctx);
+                       isc_buffer_free(&wirebuf);
+               }
+       }
+
+       isc_time_t finish;
+       isc_time_now_hires(&finish);
+       uint64_t microseconds = isc_time_microdiff(&finish, &start);
+       printf("time %f\n", (double)microseconds / (repeat * 1000000.0));
+       printf("count %u\n", count);
+
+       for (int i = 1; i < argc; i++) {
+               dns_message_detach(&message[i]);
+       }
+
+       isc_mem_free(mctx, message);
+       isc_mem_destroy(&mctx);
+
+       return (0);
+}