diff --git a/benchmarks/benchmarks.vcxproj b/benchmarks/benchmarks.vcxproj
index 5906f20a3d..f3b065bf92 100644
--- a/benchmarks/benchmarks.vcxproj
+++ b/benchmarks/benchmarks.vcxproj
@@ -18,6 +18,7 @@
+
diff --git a/benchmarks/benchmarks.vcxproj.filters b/benchmarks/benchmarks.vcxproj.filters
index 8241497894..1b2d5219a1 100644
--- a/benchmarks/benchmarks.vcxproj.filters
+++ b/benchmarks/benchmarks.vcxproj.filters
@@ -86,6 +86,9 @@
Source Files
+
+ Source Files
+
diff --git a/benchmarks/elementary_functions_benchmark.cpp b/benchmarks/elementary_functions_benchmark.cpp
new file mode 100644
index 0000000000..10d839c58c
--- /dev/null
+++ b/benchmarks/elementary_functions_benchmark.cpp
@@ -0,0 +1,55 @@
+// .\Release\x64\benchmarks.exe --benchmark_repetitions=3 --benchmark_filter=BM_EvaluateElementaryFunction // NOLINT(whitespace/line_length)
+
+#include
+#include
+
+#include "benchmark/benchmark.h"
+
+namespace principia {
+namespace functions {
+
+static constexpr std::int64_t number_of_iterations = 1000;
+
+enum class Metric { Latency, Throughput };
+
+template
+void BM_EvaluateElementaryFunction(benchmark::State& state) {
+ using Value = double;
+ using Argument = double;
+
+ std::mt19937_64 random(42);
+ std::uniform_real_distribution<> uniformly_at(-1.0, 1.0);
+ Argument argument = uniformly_at(random);
+
+ if constexpr (metric == Metric::Throughput) {
+ Value v[number_of_iterations];
+ while (state.KeepRunningBatch(number_of_iterations)) {
+ for (std::int64_t i = 0; i < number_of_iterations; ++i) {
+ v[i] = fn(argument);
+ }
+ benchmark::DoNotOptimize(v);
+ }
+ } else {
+ static_assert(metric == Metric::Latency);
+ Value v;
+ while (state.KeepRunningBatch(number_of_iterations)) {
+ for (std::int64_t i = 0; i < number_of_iterations; ++i) {
+ v = fn(argument);
+ argument = v;
+ }
+ }
+ }
+}
+
+BENCHMARK_TEMPLATE(BM_EvaluateElementaryFunction, Metric::Latency, std::sin)
+ ->Unit(benchmark::kNanosecond);
+BENCHMARK_TEMPLATE(BM_EvaluateElementaryFunction, Metric::Throughput, std::sin)
+ ->Unit(benchmark::kNanosecond);
+
+BENCHMARK_TEMPLATE(BM_EvaluateElementaryFunction, Metric::Latency, std::cos)
+ ->Unit(benchmark::kNanosecond);
+BENCHMARK_TEMPLATE(BM_EvaluateElementaryFunction, Metric::Throughput, std::cos)
+ ->Unit(benchmark::kNanosecond);
+
+} // namespace functions
+} // namespace principia