summaryrefslogtreecommitdiffstats
path: root/fluent-bit/lib/avro/tests/performance.c
diff options
context:
space:
mode:
Diffstat (limited to 'fluent-bit/lib/avro/tests/performance.c')
-rw-r--r--fluent-bit/lib/avro/tests/performance.c848
1 files changed, 848 insertions, 0 deletions
diff --git a/fluent-bit/lib/avro/tests/performance.c b/fluent-bit/lib/avro/tests/performance.c
new file mode 100644
index 00000000..a6f50427
--- /dev/null
+++ b/fluent-bit/lib/avro/tests/performance.c
@@ -0,0 +1,848 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include "avro.h"
+#include "avro_private.h"
+
+
+/* The following definitions can be used as bitflags. They can also be
+ * passed in as the resolution_mode flags to the helper functions.
+ */
+#define USE_MATCHED_SCHEMAS (0x00)
+#define USE_RESOLVED_READER (0x01)
+#define USE_RESOLVED_WRITER (0x02)
+#define USE_BOTH_RESOLVED (0x03)
+
+
+/*
+ * A series of performance tests.
+ */
+
+typedef void
+(*test_func_t)(unsigned long);
+
+
+void init_rand(void)
+{
+ srand(time(NULL));
+}
+
+double rand_number(double from, double to)
+{
+ double range = to - from;
+ return from + ((double)rand() / (RAND_MAX + 1.0)) * range;
+}
+
+int64_t rand_int64(void)
+{
+ return (int64_t) rand_number(LONG_MIN, LONG_MAX);
+}
+
+int32_t rand_int32(void)
+{
+ return (int32_t) rand_number(INT_MIN, INT_MAX);
+}
+
+
+/**
+ * Tests the single-threaded performance of our reference counting
+ * mechanism. We create a single datum, and then reference and
+ * deference it many many times.
+ */
+
+static void
+test_refcount(unsigned long num_tests)
+{
+ unsigned long i;
+
+ avro_datum_t datum = avro_int32(42);
+ for (i = 0; i < num_tests; i++) {
+ avro_datum_incref(datum);
+ avro_datum_decref(datum);
+ }
+ avro_datum_decref(datum);
+}
+
+
+/**
+ * Tests the performance of serializing and deserializing a somewhat
+ * complex record type using the legacy datum API.
+ */
+
+static void
+test_nested_record_datum(unsigned long num_tests)
+{
+ static const char *schema_json =
+ "{"
+ " \"type\": \"record\","
+ " \"name\": \"test\","
+ " \"fields\": ["
+ " { \"name\": \"i\", \"type\": \"int\" },"
+ " { \"name\": \"l\", \"type\": \"long\" },"
+ " { \"name\": \"s\", \"type\": \"string\" },"
+ " {"
+ " \"name\": \"subrec\","
+ " \"type\": {"
+ " \"type\": \"record\","
+ " \"name\": \"sub\","
+ " \"fields\": ["
+ " { \"name\": \"f\", \"type\": \"float\" },"
+ " { \"name\": \"d\", \"type\": \"double\" }"
+ " ]"
+ " }"
+ " }"
+ " ]"
+ "}";
+
+ static const char *strings[] = {
+ "Four score and seven years ago",
+ "our father brought forth on this continent",
+ "a new nation", "conceived in Liberty",
+ "and dedicated to the proposition that all men are created equal."
+ };
+ static const unsigned int NUM_STRINGS =
+ sizeof(strings) / sizeof(strings[0]);
+
+ int rc;
+ static char buf[4096];
+ avro_reader_t reader = avro_reader_memory(buf, sizeof(buf));
+ avro_writer_t writer = avro_writer_memory(buf, sizeof(buf));
+
+ avro_schema_t schema = NULL;
+ avro_schema_error_t error = NULL;
+ avro_schema_from_json(schema_json, strlen(schema_json),
+ &schema, &error);
+
+ unsigned long i;
+
+ avro_datum_t in = avro_datum_from_schema(schema);
+
+ for (i = 0; i < num_tests; i++) {
+ avro_record_set_field_value(rc, in, int32, "i", rand_int32());
+ avro_record_set_field_value(rc, in, int64, "l", rand_int64());
+ avro_record_set_field_value(rc, in, givestring, "s",
+ strings[i % NUM_STRINGS], NULL);
+
+ avro_datum_t subrec = NULL;
+ avro_record_get(in, "subrec", &subrec);
+ avro_record_set_field_value(rc, in, float, "f", rand_number(-1e10, 1e10));
+ avro_record_set_field_value(rc, in, double, "d", rand_number(-1e10, 1e10));
+
+ avro_writer_reset(writer);
+ avro_write_data(writer, schema, in);
+
+ avro_datum_t out = NULL;
+
+ avro_reader_reset(reader);
+ avro_read_data(reader, schema, schema, &out);
+
+ avro_datum_equal(in, out);
+ avro_datum_decref(out);
+ }
+
+ avro_datum_decref(in);
+ avro_schema_decref(schema);
+ avro_writer_free(writer);
+ avro_reader_free(reader);
+}
+
+
+/**
+ * Tests the performance of serializing and deserializing a somewhat
+ * complex record type using the new value API, retrieving record fields
+ * by index.
+ */
+
+static void
+test_nested_record_value_by_index(unsigned long num_tests)
+{
+ static const char *schema_json =
+ "{"
+ " \"type\": \"record\","
+ " \"name\": \"test\","
+ " \"fields\": ["
+ " { \"name\": \"i\", \"type\": \"int\" },"
+ " { \"name\": \"l\", \"type\": \"long\" },"
+ " { \"name\": \"s\", \"type\": \"string\" },"
+ " {"
+ " \"name\": \"subrec\","
+ " \"type\": {"
+ " \"type\": \"record\","
+ " \"name\": \"sub\","
+ " \"fields\": ["
+ " { \"name\": \"f\", \"type\": \"float\" },"
+ " { \"name\": \"d\", \"type\": \"double\" }"
+ " ]"
+ " }"
+ " }"
+ " ]"
+ "}";
+
+ static char *strings[] = {
+ "Four score and seven years ago",
+ "our father brought forth on this continent",
+ "a new nation", "conceived in Liberty",
+ "and dedicated to the proposition that all men are created equal."
+ };
+ static const unsigned int NUM_STRINGS =
+ sizeof(strings) / sizeof(strings[0]);
+
+ static char buf[4096];
+ avro_reader_t reader = avro_reader_memory(buf, sizeof(buf));
+ avro_writer_t writer = avro_writer_memory(buf, sizeof(buf));
+
+ avro_schema_t schema = NULL;
+ avro_schema_error_t error = NULL;
+ avro_schema_from_json(schema_json, strlen(schema_json),
+ &schema, &error);
+
+ unsigned long i;
+
+ avro_value_iface_t *iface = avro_generic_class_from_schema(schema);
+
+ avro_value_t val;
+ avro_generic_value_new(iface, &val);
+
+ avro_value_t out;
+ avro_generic_value_new(iface, &out);
+
+ for (i = 0; i < num_tests; i++) {
+ avro_value_t field;
+
+ avro_value_get_by_index(&val, 0, &field, NULL);
+ avro_value_set_int(&field, rand_int32());
+
+ avro_value_get_by_index(&val, 1, &field, NULL);
+ avro_value_set_long(&field, rand_int64());
+
+ avro_wrapped_buffer_t wbuf;
+ avro_wrapped_buffer_new_string(&wbuf, strings[i % NUM_STRINGS]);
+ avro_value_get_by_index(&val, 2, &field, NULL);
+ avro_value_give_string_len(&field, &wbuf);
+
+ avro_value_t subrec;
+ avro_value_get_by_index(&val, 3, &subrec, NULL);
+
+ avro_value_get_by_index(&subrec, 0, &field, NULL);
+ avro_value_set_float(&field, rand_number(-1e10, 1e10));
+
+ avro_value_get_by_index(&subrec, 1, &field, NULL);
+ avro_value_set_double(&field, rand_number(-1e10, 1e10));
+
+ avro_writer_reset(writer);
+ avro_value_write(writer, &val);
+
+ avro_reader_reset(reader);
+ avro_value_read(reader, &out);
+
+ if (! avro_value_equal_fast(&val, &out) ) {
+ printf("Broken\n");
+ exit (1);
+ }
+ }
+
+ avro_value_decref(&val);
+ avro_value_decref(&out);
+ avro_value_iface_decref(iface);
+ avro_schema_decref(schema);
+ avro_writer_free(writer);
+ avro_reader_free(reader);
+}
+
+
+
+/**
+ * Tests the performance of serializing and deserializing a somewhat
+ * complex record type using the new value API, retrieving record fields
+ * by name.
+ */
+
+static void
+test_nested_record_value_by_name(unsigned long num_tests)
+{
+ static const char *schema_json =
+ "{"
+ " \"type\": \"record\","
+ " \"name\": \"test\","
+ " \"fields\": ["
+ " { \"name\": \"i\", \"type\": \"int\" },"
+ " { \"name\": \"l\", \"type\": \"long\" },"
+ " { \"name\": \"s\", \"type\": \"string\" },"
+ " {"
+ " \"name\": \"subrec\","
+ " \"type\": {"
+ " \"type\": \"record\","
+ " \"name\": \"sub\","
+ " \"fields\": ["
+ " { \"name\": \"f\", \"type\": \"float\" },"
+ " { \"name\": \"d\", \"type\": \"double\" }"
+ " ]"
+ " }"
+ " }"
+ " ]"
+ "}";
+
+ static char *strings[] = {
+ "Four score and seven years ago",
+ "our father brought forth on this continent",
+ "a new nation", "conceived in Liberty",
+ "and dedicated to the proposition that all men are created equal."
+ };
+ static const unsigned int NUM_STRINGS =
+ sizeof(strings) / sizeof(strings[0]);
+
+ static char buf[4096];
+ avro_reader_t reader = avro_reader_memory(buf, sizeof(buf));
+ avro_writer_t writer = avro_writer_memory(buf, sizeof(buf));
+
+ avro_schema_t schema = NULL;
+ avro_schema_error_t error = NULL;
+ avro_schema_from_json(schema_json, strlen(schema_json),
+ &schema, &error);
+
+ unsigned long i;
+
+ avro_value_iface_t *iface = avro_generic_class_from_schema(schema);
+
+ avro_value_t val;
+ avro_generic_value_new(iface, &val);
+
+ avro_value_t out;
+ avro_generic_value_new(iface, &out);
+
+ for (i = 0; i < num_tests; i++) {
+ avro_value_t field;
+
+ avro_value_get_by_name(&val, "i", &field, NULL);
+ avro_value_set_int(&field, rand_int32());
+
+ avro_value_get_by_name(&val, "l", &field, NULL);
+ avro_value_set_long(&field, rand_int64());
+
+ avro_wrapped_buffer_t wbuf;
+ avro_wrapped_buffer_new_string(&wbuf, strings[i % NUM_STRINGS]);
+ avro_value_get_by_name(&val, "s", &field, NULL);
+ avro_value_give_string_len(&field, &wbuf);
+
+ avro_value_t subrec;
+ avro_value_get_by_name(&val, "subrec", &subrec, NULL);
+
+ avro_value_get_by_name(&subrec, "f", &field, NULL);
+ avro_value_set_float(&field, rand_number(-1e10, 1e10));
+
+ avro_value_get_by_name(&subrec, "d", &field, NULL);
+ avro_value_set_double(&field, rand_number(-1e10, 1e10));
+
+ avro_writer_reset(writer);
+ avro_value_write(writer, &val);
+
+ avro_reader_reset(reader);
+ avro_value_read(reader, &out);
+
+ if (! avro_value_equal_fast(&val, &out) ) {
+ printf("Broken\n");
+ exit (1);
+ }
+ }
+
+ avro_value_decref(&val);
+ avro_value_decref(&out);
+ avro_value_iface_decref(iface);
+ avro_schema_decref(schema);
+ avro_writer_free(writer);
+ avro_reader_free(reader);
+}
+
+
+
+/**
+ * Helper function to test the performance of serializing and
+ * deserializing a given avro value using the provided function to
+ * populate avro value using the new value API. Allows testing using
+ * matching schemas or using schema resolution.
+ */
+
+static void
+test_generic_helper( unsigned long num_tests,
+ int resolution_type,
+ const char *schema_json,
+ void (*populate_value_func)(avro_value_t *,
+ unsigned long)
+ )
+{
+ static char buf[4096];
+
+ avro_reader_t reader = avro_reader_memory(buf, sizeof(buf));
+ avro_writer_t writer = avro_writer_memory(buf, sizeof(buf));
+
+ avro_schema_t schema = NULL;
+ avro_schema_error_t error = NULL;
+ avro_schema_from_json(schema_json, strlen(schema_json),
+ &schema, &error);
+
+ unsigned long i;
+
+ avro_value_iface_t *writer_iface = avro_generic_class_from_schema(schema);
+ avro_value_iface_t *reader_iface = avro_generic_class_from_schema(schema);
+
+ avro_value_t val;
+ avro_generic_value_new(writer_iface, &val);
+
+ avro_value_t out;
+ avro_generic_value_new(reader_iface, &out);
+
+ /* Use resolved reader to resolve schemas while writing data to memory */
+ avro_value_iface_t *resolved_reader_iface = NULL;
+ avro_value_t resolved_reader_value;
+ if ( resolution_type & USE_RESOLVED_READER ) {
+ resolved_reader_iface = avro_resolved_reader_new( schema, schema );
+ avro_resolved_reader_new_value( resolved_reader_iface,
+ &resolved_reader_value );
+ avro_resolved_reader_set_source( &resolved_reader_value, &val );
+ }
+
+ /* Use resolved writer to resolve schemas while reading data from memory */
+ avro_value_iface_t *resolved_writer_iface = NULL;
+ avro_value_t resolved_writer_value;
+ if ( resolution_type & USE_RESOLVED_WRITER ) {
+ resolved_writer_iface = avro_resolved_writer_new( schema, schema );
+ avro_resolved_writer_new_value( resolved_writer_iface,
+ &resolved_writer_value );
+ avro_resolved_writer_set_dest( &resolved_writer_value, &out );
+ }
+
+ /* Set up pointers */
+ avro_value_t *p_value_to_write_to_memory = NULL;
+ avro_value_t *p_value_to_read_from_memory = NULL;
+
+ if ( resolution_type == USE_MATCHED_SCHEMAS ) {
+ p_value_to_write_to_memory = &val;
+ p_value_to_read_from_memory = &out;
+ }
+ else if ( resolution_type == USE_RESOLVED_READER ) {
+ p_value_to_write_to_memory = &resolved_reader_value;
+ p_value_to_read_from_memory = &out;
+ }
+ else if ( resolution_type == USE_RESOLVED_WRITER ) {
+ p_value_to_write_to_memory = &val;
+ p_value_to_read_from_memory = &resolved_writer_value;
+ }
+ else if ( resolution_type == USE_BOTH_RESOLVED ) {
+ p_value_to_write_to_memory = &resolved_reader_value;
+ p_value_to_read_from_memory = &resolved_writer_value;
+ }
+
+ /* Perform the tests */
+ for (i = 0; i < num_tests; i++) {
+
+ avro_value_reset(&val);
+
+ /* Execute the function to populate the Avro Value */
+ (*populate_value_func)(&val, i);
+
+ avro_writer_reset(writer);
+ avro_value_write(writer, p_value_to_write_to_memory);
+
+ avro_reader_reset(reader);
+ avro_value_read(reader, p_value_to_read_from_memory);
+
+ if (! avro_value_equal_fast(&val, &out) ) {
+ printf("Broken\n");
+ exit (1);
+ }
+ }
+
+ avro_value_decref(&val);
+ avro_value_decref(&out);
+ if ( resolution_type & USE_RESOLVED_READER ) {
+ avro_value_decref(&resolved_reader_value);
+ avro_value_iface_decref(resolved_reader_iface);
+ }
+ if ( resolution_type & USE_RESOLVED_WRITER ) {
+ avro_value_decref(&resolved_writer_value);
+ avro_value_iface_decref(resolved_writer_iface);
+ }
+ avro_value_iface_decref(writer_iface);
+ avro_value_iface_decref(reader_iface);
+ avro_schema_decref(schema);
+ avro_writer_free(writer);
+ avro_reader_free(reader);
+}
+
+
+
+
+/**
+ * Helper function to populate a somewhat complex record type using
+ * the new value API, retrieving record fields by index.
+ */
+
+static const char *complex_record_schema_json =
+ "{"
+ " \"type\": \"record\","
+ " \"name\": \"test\","
+ " \"fields\": ["
+ " { \"name\": \"i\", \"type\": \"int\" },"
+ " { \"name\": \"l\", \"type\": \"long\" },"
+ " { \"name\": \"s\", \"type\": \"string\" },"
+ " {"
+ " \"name\": \"subrec\","
+ " \"type\": {"
+ " \"type\": \"record\","
+ " \"name\": \"sub\","
+ " \"fields\": ["
+ " { \"name\": \"f\", \"type\": \"float\" },"
+ " { \"name\": \"d\", \"type\": \"double\" }"
+ " ]"
+ " }"
+ " }"
+ " ]"
+ "}";
+
+
+
+static void
+populate_complex_record(avro_value_t *p_val, unsigned long i)
+{
+ static char *strings[] = {
+ "Four score and seven years ago",
+ "our father brought forth on this continent",
+ "a new nation", "conceived in Liberty",
+ "and dedicated to the proposition that all men are created equal."
+ };
+ static const unsigned int NUM_STRINGS =
+ sizeof(strings) / sizeof(strings[0]);
+
+ avro_value_t field;
+
+ avro_value_get_by_index(p_val, 0, &field, NULL);
+ avro_value_set_int(&field, rand_int32());
+
+ avro_value_get_by_index(p_val, 1, &field, NULL);
+ avro_value_set_long(&field, rand_int64());
+
+ avro_wrapped_buffer_t wbuf;
+ avro_wrapped_buffer_new_string(&wbuf, strings[i % NUM_STRINGS]);
+ avro_value_get_by_index(p_val, 2, &field, NULL);
+ avro_value_give_string_len(&field, &wbuf);
+
+ avro_value_t subrec;
+ avro_value_get_by_index(p_val, 3, &subrec, NULL);
+
+ avro_value_get_by_index(&subrec, 0, &field, NULL);
+ avro_value_set_float(&field, rand_number(-1e10, 1e10));
+
+ avro_value_get_by_index(&subrec, 1, &field, NULL);
+ avro_value_set_double(&field, rand_number(-1e10, 1e10));
+
+}
+
+
+
+/**
+ * Tests the performance of serializing and deserializing a somewhat
+ * complex record type using the new value API, retrieving record
+ * fields by index. The functionality is almost identical to
+ * test_nested_record_value_by_index(), however, there may be some
+ * overhead of using function calls instead of inline code, and
+ * running some additional "if" statements..
+ */
+
+static void
+test_nested_record_value_by_index_matched_schemas(unsigned long num_tests)
+{
+ test_generic_helper(num_tests,
+ USE_MATCHED_SCHEMAS,
+ complex_record_schema_json,
+ populate_complex_record);
+}
+
+
+/**
+ * Tests the performance of serializing and deserializing a somewhat
+ * complex record type using the new value API, retrieving record
+ * fields by index. Uses a resolved_writer to resolve between two
+ * (identical) schemas when reading the array.
+ */
+
+static void
+test_nested_record_value_by_index_resolved_writer(unsigned long num_tests)
+{
+ test_generic_helper(num_tests,
+ USE_RESOLVED_WRITER,
+ complex_record_schema_json,
+ populate_complex_record);
+}
+
+
+
+/**
+ * Tests the performance of serializing and deserializing a somewhat
+ * complex record type using the new value API, retrieving record
+ * fields by index. Uses a resolved_reader to resolve between two
+ * (identical) schemas when writing the array.
+ */
+
+static void
+test_nested_record_value_by_index_resolved_reader(unsigned long num_tests)
+{
+ test_generic_helper(num_tests,
+ USE_RESOLVED_READER,
+ complex_record_schema_json,
+ populate_complex_record);
+}
+
+
+
+/**
+ * Helper function to test the performance of serializing and
+ * deserializing a simple array using the new value API. Allows
+ * testing using matching schemas or using schema resolution.
+ */
+
+static const char *simple_array_schema_json =
+ "{\"name\": \"a\", \"type\": \"array\", \"items\":\"long\"}";
+
+static void
+populate_simple_array(avro_value_t *p_val, unsigned long i)
+{
+ const size_t array_length = 21;
+ avro_value_t field;
+ size_t idx;
+ size_t dummy_index;
+ (void) i;
+
+ for ( idx = 0; idx < array_length; idx++ ) {
+ avro_value_append(p_val, &field, &dummy_index);
+ avro_value_set_long(&field, rand_int64());
+ }
+}
+
+
+
+/**
+ * Tests the performance of serializing and deserializing a simple
+ * array using the new value API.
+ */
+
+static void
+test_simple_array(unsigned long num_tests)
+{
+ test_generic_helper(num_tests,
+ USE_MATCHED_SCHEMAS,
+ simple_array_schema_json,
+ populate_simple_array);
+}
+
+
+
+/**
+ * Tests the performance of serializing and deserializing a simple
+ * array using the new value API, using a resolved writer to resolve
+ * between (identical) reader and writer schemas, when reading the
+ * array.
+ */
+static void
+test_simple_array_resolved_writer(unsigned long num_tests)
+{
+ test_generic_helper(num_tests,
+ USE_RESOLVED_WRITER,
+ simple_array_schema_json,
+ populate_simple_array);
+}
+
+
+
+/**
+ * Tests the performance of serializing and deserializing a simple
+ * array using the new value API, using a resolved reader to resolve
+ * between (identical) reader and writer schemas, when writing the
+ * array.
+ */
+
+static void
+test_simple_array_resolved_reader(unsigned long num_tests)
+{
+ test_generic_helper(num_tests,
+ USE_RESOLVED_READER,
+ simple_array_schema_json,
+ populate_simple_array);
+}
+
+
+
+
+/**
+ * Helper function to test the performance of serializing and
+ * deserializing a nested array using the new value API. Allows
+ * testing using matching schemas or using schema resolution.
+ */
+
+static const char *nested_array_schema_json =
+ "{\"type\":\"array\", \"items\": {\"type\": \"array\", \"items\": \"long\"}}";
+
+
+static void
+populate_nested_array(avro_value_t *p_val, unsigned long i)
+{
+
+ const size_t array_length = 7;
+ const size_t subarray_length = 3;
+ avro_value_t subarray;
+ avro_value_t field;
+ size_t idx;
+ size_t jdx;
+ size_t dummy_index;
+ (void) i;
+
+ for ( idx = 0; idx < array_length; idx++ ) {
+ avro_value_append(p_val, &subarray, &dummy_index);
+ for ( jdx = 0; jdx < subarray_length; jdx ++ ) {
+ avro_value_append(&subarray, &field, &dummy_index);
+ avro_value_set_long(&field, rand_int64());
+ }
+ }
+}
+
+
+/**
+ * Tests the performance of serializing and deserializing a nested
+ * array using the new value API.
+ */
+
+static void
+test_nested_array(unsigned long num_tests)
+{
+ test_generic_helper(num_tests,
+ USE_MATCHED_SCHEMAS,
+ nested_array_schema_json,
+ populate_nested_array);
+}
+
+
+/**
+ * Tests the performance of serializing and deserializing a nested
+ * array using the new value API, using a resolved writer to resolve
+ * between (identical) reader and writer schemas, when reading the
+ * array.
+ */
+
+static void
+test_nested_array_resolved_writer(unsigned long num_tests)
+{
+ test_generic_helper(num_tests,
+ USE_RESOLVED_WRITER,
+ nested_array_schema_json,
+ populate_nested_array);
+}
+
+
+/**
+ * Tests the performance of serializing and deserializing a nested
+ * array using the new value API, using a resolved reader to resolve
+ * between (identical) reader and writer schemas, when writing the
+ * array.
+ */
+
+static void
+test_nested_array_resolved_reader(unsigned long num_tests)
+{
+ test_generic_helper(num_tests,
+ USE_RESOLVED_READER,
+ nested_array_schema_json,
+ populate_nested_array);
+}
+
+
+
+/**
+ * Test harness
+ */
+
+#define NUM_RUNS 3
+
+int
+main(int argc, char **argv)
+{
+ AVRO_UNUSED(argc);
+ AVRO_UNUSED(argv);
+
+ init_rand();
+
+ unsigned int i;
+ struct avro_tests {
+ const char *name;
+ unsigned long num_tests;
+ test_func_t func;
+ } tests[] = {
+ { "refcount", 100000000,
+ test_refcount },
+ { "nested record (legacy)", 100000,
+ test_nested_record_datum },
+ { "nested record (value by index)", 1000000,
+ test_nested_record_value_by_index },
+ { "nested record (value by name)", 1000000,
+ test_nested_record_value_by_name },
+ { "nested record (value by index) matched schemas", 1000000,
+ test_nested_record_value_by_index_matched_schemas },
+ { "nested record (value by index) resolved writer", 1000000,
+ test_nested_record_value_by_index_resolved_writer },
+ { "nested record (value by index) resolved reader", 1000000,
+ test_nested_record_value_by_index_resolved_reader },
+ { "simple array matched schemas", 250000,
+ test_simple_array },
+ { "simple array resolved writer", 250000,
+ test_simple_array_resolved_writer },
+ { "simple array resolved reader", 250000,
+ test_simple_array_resolved_reader },
+ { "nested array matched schemas", 250000,
+ test_nested_array },
+ { "nested array resolved writer", 250000,
+ test_nested_array_resolved_writer },
+ { "nested array resolved reader", 250000,
+ test_nested_array_resolved_reader },
+ };
+
+ for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) {
+ fprintf(stderr, "**** Running %s ****\n %lu tests per run\n",
+ tests[i].name, tests[i].num_tests);
+ unsigned int run;
+
+ double sum = 0.0;
+
+ for (run = 1; run <= NUM_RUNS; run++) {
+ fprintf(stderr, " Run %u\n", run);
+
+ clock_t before = clock();
+ tests[i].func(tests[i].num_tests);
+ clock_t after = clock();
+ double secs = ((double) after-before) / CLOCKS_PER_SEC;
+ sum += secs;
+ }
+
+ fprintf(stderr, " Average time: %.03lfs\n", sum / NUM_RUNS);
+ fprintf(stderr, " Tests/sec: %.0lf\n",
+ tests[i].num_tests / (sum / NUM_RUNS));
+ }
+
+ return EXIT_SUCCESS;
+}