Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion benchmarks/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,12 @@ add_executable(model_bench model_bench.cpp)
target_link_libraries(model_bench PRIVATE ada counters::counters)
target_compile_definitions(model_bench PRIVATE ADA_URL_FILE="${url-dataset_SOURCE_DIR}/out.txt")

# C API benchmark
add_executable(bench_c_api bench_c_api.cpp)
target_link_libraries(bench_c_api PRIVATE ada counters::counters)
target_include_directories(bench_c_api PUBLIC "$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>")
target_include_directories(bench_c_api PUBLIC "$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/benchmarks>")

target_link_libraries(wpt_bench PRIVATE benchmark::benchmark)
target_link_libraries(bench PRIVATE benchmark::benchmark)
target_link_libraries(benchdata PRIVATE benchmark::benchmark)
Expand All @@ -80,8 +86,9 @@ target_link_libraries(bench_ipv4 PRIVATE benchmark::benchmark)
target_link_libraries(percent_encode PRIVATE benchmark::benchmark)
target_link_libraries(bench_search_params PRIVATE benchmark::benchmark)
target_link_libraries(urlpattern PRIVATE benchmark::benchmark)
target_link_libraries(bench_c_api PRIVATE benchmark::benchmark)

set(BENCHMARKS wpt_bench bench benchdata bbc_bench bench_ipv4 percent_encode bench_search_params urlpattern)
set(BENCHMARKS wpt_bench bench benchdata bbc_bench bench_ipv4 percent_encode bench_search_params urlpattern bench_c_api)

add_custom_target(run_all_benchmarks
COMMAND ${CMAKE_COMMAND} -E echo "Running all benchmarks..."
Expand Down
242 changes: 242 additions & 0 deletions benchmarks/bench_c_api.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,242 @@
/**
* @file bench_c_api.cpp
* @brief Google Benchmark-based benchmarks for the ada C API (ada_c.h).
*
* Mirrors the structure of bench.cpp / benchmark_template.cpp but exercises
* the pure-C entry points (ada_parse, ada_can_parse, getters, setters, search
* params) so their performance can be compared directly with the C++ API.
*/
#include "benchmark_header.h"

extern "C" {
#include "ada_c.h"
}

// ---------------------------------------------------------------------------
// URL dataset (shared with the existing C++ benchmarks)
// ---------------------------------------------------------------------------

std::string c_api_url_examples_default[] = {
"https://www.google.com/"
"webhp?hl=en&amp;ictx=2&amp;sa=X&amp;ved=0ahUKEwil_"
"oSxzJj8AhVtEFkFHTHnCGQQPQgI",
"https://support.google.com/websearch/"
"?p=ws_results_help&amp;hl=en-CA&amp;fg=1",
"https://en.wikipedia.org/wiki/Dog#Roles_with_humans",
"https://www.tiktok.com/@aguyandagolden/video/7133277734310038830",
"https://business.twitter.com/en/help/troubleshooting/"
"how-twitter-ads-work.html?ref=web-twc-ao-gbl-adsinfo&utm_source=twc&utm_"
"medium=web&utm_campaign=ao&utm_content=adsinfo",
"https://images-na.ssl-images-amazon.com/images/I/"
"41Gc3C8UysL.css?AUIClients/AmazonGatewayAuiAssets",
"https://www.reddit.com/?after=t3_zvz1ze",
"https://www.reddit.com/login/?dest=https%3A%2F%2Fwww.reddit.com%2F",
"postgresql://other:9818274x1!!@localhost:5432/"
"otherdb?connect_timeout=10&application_name=myapp",
"http://192.168.1.1",
"http://[2606:4700:4700::1111]",
};

std::vector<std::string> c_api_url_examples;
double c_api_url_examples_bytes = 0.0;

// Called once from main() via BENCHMARK (see below).
size_t c_api_init_data() {
if (!c_api_url_examples.empty()) return c_api_url_examples.size();
for (const std::string& s : c_api_url_examples_default) {
c_api_url_examples.emplace_back(s);
}
for (const std::string& s : c_api_url_examples) {
c_api_url_examples_bytes += static_cast<double>(s.size());
}
return c_api_url_examples.size();
}

// ---------------------------------------------------------------------------
// Helper: emit standard throughput counters, matching benchmark_template.cpp
// ---------------------------------------------------------------------------

static void add_throughput_counters(benchmark::State& state,
double bytes,
size_t n_urls) {
state.counters["time/byte"] = benchmark::Counter(
bytes, benchmark::Counter::kIsIterationInvariantRate |
benchmark::Counter::kInvert);
state.counters["time/url"] = benchmark::Counter(
static_cast<double>(n_urls),
benchmark::Counter::kIsIterationInvariantRate |
benchmark::Counter::kInvert);
state.counters["speed"] = benchmark::Counter(
bytes, benchmark::Counter::kIsIterationInvariantRate);
state.counters["url/s"] = benchmark::Counter(
static_cast<double>(n_urls),
benchmark::Counter::kIsIterationInvariantRate);
}

// ---------------------------------------------------------------------------
// ada_parse + ada_get_href (C equivalent of BasicBench_AdaURL_aggregator_href)
// ---------------------------------------------------------------------------

static void BasicBench_C_API_parse_href(benchmark::State& state) {
c_api_init_data();
volatile size_t success = 0;
volatile size_t href_size = 0;

for (auto _ : state) {
for (const std::string& url_string : c_api_url_examples) {
ada_url url = ada_parse(url_string.data(), url_string.size());
if (ada_is_valid(url)) {
success++;
href_size += ada_get_href(url).length;
}
ada_free(url);
}
}
(void)success;
(void)href_size;
add_throughput_counters(state, c_api_url_examples_bytes,
c_api_url_examples.size());
}
BENCHMARK(BasicBench_C_API_parse_href);

// ---------------------------------------------------------------------------
// ada_can_parse (C equivalent of BasicBench_AdaURL_CanParse)
// ---------------------------------------------------------------------------

static void BasicBench_C_API_can_parse(benchmark::State& state) {
c_api_init_data();
volatile size_t success = 0;

for (auto _ : state) {
for (const std::string& url_string : c_api_url_examples) {
if (ada_can_parse(url_string.data(), url_string.size())) {
success++;
}
}
}
(void)success;
add_throughput_counters(state, c_api_url_examples_bytes,
c_api_url_examples.size());
}
BENCHMARK(BasicBench_C_API_can_parse);

// ---------------------------------------------------------------------------
// ada_parse + all getters
// ---------------------------------------------------------------------------

static void BasicBench_C_API_parse_all_getters(benchmark::State& state) {
c_api_init_data();
volatile size_t total = 0;

for (auto _ : state) {
for (const std::string& url_string : c_api_url_examples) {
ada_url url = ada_parse(url_string.data(), url_string.size());
if (ada_is_valid(url)) {
total += ada_get_href(url).length;
total += ada_get_protocol(url).length;
total += ada_get_username(url).length;
total += ada_get_password(url).length;
total += ada_get_host(url).length;
total += ada_get_hostname(url).length;
total += ada_get_port(url).length;
total += ada_get_pathname(url).length;
total += ada_get_search(url).length;
total += ada_get_hash(url).length;
ada_owned_string origin = ada_get_origin(url);
total += origin.length;
ada_free_owned_string(origin);
}
ada_free(url);
}
}
(void)total;
add_throughput_counters(state, c_api_url_examples_bytes,
c_api_url_examples.size());
}
BENCHMARK(BasicBench_C_API_parse_all_getters);

// ---------------------------------------------------------------------------
// ada_parse + ada_set_href (setter round-trip)
// ---------------------------------------------------------------------------

static void BasicBench_C_API_set_href(benchmark::State& state) {
c_api_init_data();
volatile size_t success = 0;
static const char kNewHref[] = "https://example.com/new?q=bench#frag";
static const size_t kNewHrefLen = sizeof(kNewHref) - 1;

for (auto _ : state) {
for (const std::string& url_string : c_api_url_examples) {
ada_url url = ada_parse(url_string.data(), url_string.size());
if (ada_is_valid(url)) {
if (ada_set_href(url, kNewHref, kNewHrefLen)) {
success++;
}
}
ada_free(url);
}
}
(void)success;
add_throughput_counters(state, c_api_url_examples_bytes,
c_api_url_examples.size());
}
BENCHMARK(BasicBench_C_API_set_href);

// ---------------------------------------------------------------------------
// ada_parse_search_params + iterate entries
// ---------------------------------------------------------------------------

static void BasicBench_C_API_search_params(benchmark::State& state) {
static const char kQuery[] =
"key1=value1&key2=value2&key3=value3&key4=value4&key5=value5";
static const size_t kQueryLen = sizeof(kQuery) - 1;

volatile size_t total = 0;

for (auto _ : state) {
ada_url_search_params params = ada_parse_search_params(kQuery, kQueryLen);
total += ada_search_params_size(params);

ada_url_search_params_entries_iter iter =
ada_search_params_get_entries(params);
while (ada_search_params_entries_iter_has_next(iter)) {
ada_string_pair pair = ada_search_params_entries_iter_next(iter);
total += pair.key.length + pair.value.length;
}
ada_free_search_params_entries_iter(iter);
ada_free_search_params(params);
}
(void)total;
state.counters["params/s"] = benchmark::Counter(
5.0, benchmark::Counter::kIsIterationInvariantRate);
}
BENCHMARK(BasicBench_C_API_search_params);

// ---------------------------------------------------------------------------
// ada_parse + ada_copy independence
// ---------------------------------------------------------------------------

static void BasicBench_C_API_copy(benchmark::State& state) {
c_api_init_data();
volatile size_t success = 0;

for (auto _ : state) {
for (const std::string& url_string : c_api_url_examples) {
ada_url url = ada_parse(url_string.data(), url_string.size());
if (ada_is_valid(url)) {
ada_url copy = ada_copy(url);
if (ada_is_valid(copy)) {
success += ada_get_href(copy).length;
}
ada_free(copy);
}
ada_free(url);
}
}
(void)success;
add_throughput_counters(state, c_api_url_examples_bytes,
c_api_url_examples.size());
}
BENCHMARK(BasicBench_C_API_copy);

BENCHMARK_MAIN();
Binary file added build-bench/.ninja_deps
Binary file not shown.
26 changes: 26 additions & 0 deletions build-bench/.ninja_log
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# ninja log v7
3 299 1774203692853432050 src/CMakeFiles/ada.dir/ada_c.c.o 943b68b87b1f00b6
4 866 1774203692856134185 _deps/benchmark-build/src/CMakeFiles/benchmark.dir/benchmark_name.cc.o e30ac80f90a2d8db
4 1221 1774203692855836690 _deps/benchmark-build/src/CMakeFiles/benchmark.dir/benchmark_api_internal.cc.o b33b6117f4d4c50c
866 1594 1774203693716430682 _deps/benchmark-build/src/CMakeFiles/benchmark.dir/check.cc.o bfeb4bf53f9ba432
1222 2047 1774203694075430113 _deps/benchmark-build/src/CMakeFiles/benchmark.dir/colorprint.cc.o 45efbcbf381cb95f
1594 3483 1774203694444429527 _deps/benchmark-build/src/CMakeFiles/benchmark.dir/commandlineflags.cc.o d2a85aefdd1e7ef7
299 4470 1774203693150976932 _deps/benchmark-build/src/CMakeFiles/benchmark.dir/benchmark_runner.cc.o db0c4521638a9566
2047 4908 1774203694897428809 _deps/benchmark-build/src/CMakeFiles/benchmark.dir/complexity.cc.o 4613d4d039cad6b5
3483 4928 1774203696333426532 _deps/benchmark-build/src/CMakeFiles/benchmark.dir/console_reporter.cc.o 9367a9acaeea2e40
4471 5494 1774203697321423564 _deps/benchmark-build/src/CMakeFiles/benchmark.dir/counter.cc.o d59e2953811e72a8
4908 6414 1774203697758422016 _deps/benchmark-build/src/CMakeFiles/benchmark.dir/csv_reporter.cc.o 47c92da66d50d48f
5494 6723 1774203698344421482 _deps/benchmark-build/src/CMakeFiles/benchmark.dir/perf_counters.cc.o f8af7dcd6504dab5
4928 6871 1774203697778421945 _deps/benchmark-build/src/CMakeFiles/benchmark.dir/json_reporter.cc.o b751540fb0ac5816
3 7348 1774203692854918577 _deps/benchmark-build/src/CMakeFiles/benchmark.dir/benchmark.cc.o 8fdce170a7600e0c
6414 7768 1774203699264426035 _deps/benchmark-build/src/CMakeFiles/benchmark.dir/reporter.cc.o 44d534cc4aad872d
6871 8403 1774203699721428297 _deps/benchmark-build/src/CMakeFiles/benchmark.dir/string_util.cc.o 59af8cef8ac6d84
7768 8765 1774203700618429484 _deps/benchmark-build/src/CMakeFiles/benchmark.dir/timers.cc.o 37dcf29f8a41f39e
5 9371 1774203692857000712 _deps/benchmark-build/src/CMakeFiles/benchmark.dir/benchmark_register.cc.o d26b38f7da928436
6723 9385 1774203699573427564 _deps/benchmark-build/src/CMakeFiles/benchmark.dir/statistics.cc.o 341f7d96df5fd4c1
7348 9731 1774203700198430579 _deps/benchmark-build/src/CMakeFiles/benchmark.dir/sysinfo.cc.o 41b0f5f881aacf79
9731 9881 1774203702581424368 _deps/benchmark-build/src/libbenchmark.a 3fdc2257b483b8ac
8403 11064 1774203701253427829 benchmarks/CMakeFiles/bench_c_api.dir/bench_c_api.cpp.o d54a6b3e08338b69
2 19311 1774203692852432051 src/CMakeFiles/ada.dir/ada.cpp.o a4649f2495a4841a
19311 19403 1774203712161400110 src/libada.a 66ff9323f3f44e61
19403 19469 1774203712253399881 benchmarks/bench_c_api af5dbeb8d50c9239
Loading
Loading