Skip to content

Commit 381d381

Browse files
Add cache_benchmark (#679)
* Add cache_benchmark Signed-off-by: Eric Cousineau <[email protected]> Co-authored-by: Chris Lalancette <[email protected]>
1 parent a17a2bf commit 381d381

File tree

3 files changed

+105
-0
lines changed

3 files changed

+105
-0
lines changed

Diff for: tf2/CMakeLists.txt

+6
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ install(DIRECTORY include/ DESTINATION include/${PROJECT_NAME})
4444

4545
# Tests
4646
if(BUILD_TESTING)
47+
find_package(ament_cmake_google_benchmark REQUIRED)
4748
find_package(ament_cmake_copyright REQUIRED)
4849
find_package(ament_cmake_cppcheck REQUIRED)
4950
find_package(ament_cmake_cpplint REQUIRED)
@@ -83,6 +84,11 @@ if(BUILD_TESTING)
8384
target_link_libraries(test_cache_unittest tf2)
8485
endif()
8586

87+
ament_add_google_benchmark(cache_benchmark test/cache_benchmark.cpp)
88+
if(TARGET cache_benchmark)
89+
target_link_libraries(cache_benchmark tf2)
90+
endif()
91+
8692
ament_add_gtest(test_static_cache_unittest test/static_cache_test.cpp)
8793
if(TARGET test_static_cache_unittest)
8894
target_link_libraries(test_static_cache_unittest tf2)

Diff for: tf2/package.xml

+1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
<depend>geometry_msgs</depend>
3232
<depend>rcutils</depend>
3333

34+
<test_depend>ament_cmake_google_benchmark</test_depend>
3435
<test_depend>ament_cmake_gtest</test_depend>
3536
<test_depend>ament_cmake_copyright</test_depend>
3637
<test_depend>ament_cmake_cppcheck</test_depend>

Diff for: tf2/test/cache_benchmark.cpp

+98
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
// Copyright 2024, Open Source Robotics Foundation, Inc. All rights reserved.
2+
//
3+
// Redistribution and use in source and binary forms, with or without
4+
// modification, are permitted provided that the following conditions are met:
5+
//
6+
// * Redistributions of source code must retain the above copyright
7+
// notice, this list of conditions and the following disclaimer.
8+
//
9+
// * Redistributions in binary form must reproduce the above copyright
10+
// notice, this list of conditions and the following disclaimer in the
11+
// documentation and/or other materials provided with the distribution.
12+
//
13+
// * Neither the name of the Open Source Robotics Foundation, Inc. nor the
14+
// names of its contributors may be used to endorse or promote products
15+
// derived from this software without specific prior written permission.
16+
//
17+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18+
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19+
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20+
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21+
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22+
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23+
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24+
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25+
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26+
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27+
// POSSIBILITY OF SUCH DAMAGE.
28+
29+
#include <benchmark/benchmark.h>
30+
31+
#include <chrono>
32+
#include <tuple>
33+
#include <vector>
34+
35+
#include "tf2/time_cache.h"
36+
37+
// Simulates 5 transforms, 10s worth of data at 200 Hz in a buffer that is
38+
// completely full.
39+
static void benchmark_insertion(benchmark::State & state)
40+
{
41+
constexpr tf2::Duration max_storage_time = std::chrono::seconds(10);
42+
const int num_tform = 5;
43+
const int freq_hz = 200;
44+
const tf2::Duration dt = std::chrono::nanoseconds(1'000'000'000 / freq_hz);
45+
46+
// Distinct transforms.
47+
std::vector<tf2::TransformStorage> example_items{};
48+
for (int tform_index = 0; tform_index < num_tform; ++tform_index) {
49+
tf2::TransformStorage stor{};
50+
stor.child_frame_id_ = tform_index;
51+
stor.translation_.setValue(tform_index, 0.0, 0.0);
52+
stor.rotation_.setValue(0.0, 0.0, 0.0, 1.0);
53+
example_items.emplace_back(stor);
54+
}
55+
56+
// Insert data to cache
57+
auto insert_data = [&example_items, num_tform, dt](
58+
tf2::TimeCache & cache,
59+
tf2::TimePoint timestamp,
60+
int step,
61+
tf2::TimePoint target_timestamp) {
62+
while (timestamp < target_timestamp) {
63+
for (int tform_index = 0; tform_index < num_tform; ++tform_index) {
64+
example_items[tform_index].frame_id_ = step;
65+
example_items[tform_index].stamp_ = timestamp;
66+
cache.insertData(example_items[tform_index]);
67+
}
68+
timestamp += dt;
69+
++step;
70+
}
71+
return std::make_tuple(timestamp, step);
72+
};
73+
74+
// First, fill the cache with max storage amount (the limit).
75+
tf2::TimeCache fill_cache(max_storage_time);
76+
const auto [fill_timestamp, fill_timestep] = insert_data(
77+
fill_cache,
78+
tf2::TimePointZero,
79+
0,
80+
tf2::TimePointZero + max_storage_time);
81+
82+
// Now profile adding new data to the copied cache.
83+
const tf2::TimePoint target_timestamp = fill_timestamp + max_storage_time;
84+
for (auto _ : state) {
85+
// Don't profile construction (copying) of the cache.
86+
state.PauseTiming();
87+
tf2::TimeCache cache(fill_cache);
88+
state.ResumeTiming();
89+
90+
insert_data(
91+
cache,
92+
fill_timestamp,
93+
fill_timestep,
94+
target_timestamp);
95+
}
96+
}
97+
98+
BENCHMARK(benchmark_insertion);

0 commit comments

Comments
 (0)