1 /* Copyright (C) 2013 BMW Group
2 * Author: Manfred Bathelt (manfred.bathelt@bmw.de)
3 * Author: Juergen Gehring (juergen.gehring@bmw.de)
4 * This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include <CommonAPI/SerializableStruct.h>
8 #include <CommonAPI/DBus/DBusInputStream.h>
9 #include <CommonAPI/DBus/DBusOutputStream.h>
11 #include <unordered_map>
12 #include <bits/functional_hash.h>
14 #include <gtest/gtest.h>
16 #include <dbus/dbus.h>
21 #include <unordered_map>
22 #include <bits/functional_hash.h>
25 class BenchmarkingTest: public ::testing::Test {
27 DBusMessage* libdbusMessage;
28 DBusMessageIter libdbusMessageWriteIter;
33 libdbusMessage = dbus_message_new_method_call("no.bus.here", "/no/object/here", NULL, "noMethodHere");
34 ASSERT_TRUE(libdbusMessage != NULL);
35 dbus_message_iter_init_append(libdbusMessage, &libdbusMessageWriteIter);
39 dbus_message_unref(libdbusMessage);
43 template <typename _ArrayElementLibdbusType, typename _ArrayElementCommonApiType>
44 void prepareLibdbusArray(DBusMessage* libdbusMessage,
45 const int arrayElementLibdbusType,
46 const char* arrayElementLibdbusTypeAsString,
47 const _ArrayElementLibdbusType& arrayInitElementValue,
48 const uint32_t arrayInitTime,
49 size_t& libdbusInitElementCount) {
51 DBusMessageIter libdbusMessageIter;
52 DBusMessageIter libdbusMessageContainerIter;
54 dbus_message_iter_init_append(libdbusMessage, &libdbusMessageIter);
56 dbus_bool_t libdbusSuccess = dbus_message_iter_open_container(&libdbusMessageIter,
58 arrayElementLibdbusTypeAsString,
59 &libdbusMessageContainerIter);
60 ASSERT_TRUE(libdbusSuccess);
63 std::chrono::milliseconds libdbusInitTime;
64 std::chrono::time_point<std::chrono::high_resolution_clock> clockStart = std::chrono::high_resolution_clock::now();
67 for (int i = 0; i < 1000; i++)
68 dbus_message_iter_append_basic(&libdbusMessageContainerIter,
69 arrayElementLibdbusType,
70 &arrayInitElementValue);
72 libdbusInitElementCount += 1000;
74 libdbusInitTime = std::chrono::duration_cast<std::chrono::milliseconds>(
75 std::chrono::high_resolution_clock::now() - clockStart);
76 } while (libdbusInitTime.count() < arrayInitTime);
78 libdbusSuccess = dbus_message_iter_close_container(&libdbusMessageIter, &libdbusMessageContainerIter);
79 ASSERT_TRUE(libdbusSuccess);
81 std::cout << "LibdbusInitTime = " << libdbusInitTime.count() << std::endl;
82 std::cout << "LibdbusInitElementCount = " << libdbusInitElementCount << std::endl;
86 template <typename _ArrayElementLibdbusType, typename _ArrayElementCommonApiType>
87 void measureLibdbusArrayReadTime(DBusMessage* libdbusMessage,
88 size_t& libdbusInitElementCount,
89 std::chrono::milliseconds& libdbusArrayReadTime) {
91 DBusMessageIter libdbusMessageIter;
92 DBusMessageIter libdbusMessageContainerIter;
94 dbus_bool_t libdbusSuccess;
96 libdbusSuccess = dbus_message_iter_init(libdbusMessage, &libdbusMessageIter);
97 ASSERT_TRUE(libdbusSuccess);
99 dbus_message_iter_recurse(&libdbusMessageIter, &libdbusMessageContainerIter);
101 size_t libdbusReadElementCount = 0;
102 std::chrono::time_point<std::chrono::high_resolution_clock> clockStart = std::chrono::high_resolution_clock::now();
105 _ArrayElementLibdbusType libdbusValue;
107 dbus_message_iter_get_basic(&libdbusMessageContainerIter, &libdbusValue);
109 ++libdbusReadElementCount;
110 } while (dbus_message_iter_next(&libdbusMessageContainerIter));
112 libdbusArrayReadTime = std::chrono::duration_cast<std::chrono::milliseconds>(
113 std::chrono::high_resolution_clock::now() - clockStart);
115 ASSERT_EQ(libdbusInitElementCount, libdbusReadElementCount);
119 template <typename _ArrayElementLibdbusType, typename _ArrayElementCommonApiType>
120 void measureCommonApiArrayReadTime(DBusMessage* libdbusMessage,
121 std::chrono::milliseconds& commonArrayApiReadTime,
122 size_t& libdbusInitElementCount) {
124 CommonAPI::DBus::DBusMessage dbusMessage(libdbusMessage);
125 CommonAPI::DBus::DBusInputStream DBusInputStream(dbusMessage);
126 std::vector<_ArrayElementCommonApiType> commonApiVector;
128 std::chrono::time_point<std::chrono::high_resolution_clock> clockStart = std::chrono::high_resolution_clock::now();
130 DBusInputStream >> commonApiVector;
132 commonArrayApiReadTime = std::chrono::duration_cast<std::chrono::milliseconds>(
133 std::chrono::high_resolution_clock::now() - clockStart);
135 ASSERT_EQ(libdbusInitElementCount, commonApiVector.size());
139 template <typename _ArrayElementLibdbusType, typename _ArrayElementCommonApiType>
140 void measureArrayReadTime(
141 const int arrayElementLibdbusType,
142 const char* arrayElementLibdbusTypeAsString,
143 const _ArrayElementLibdbusType arrayInitElementValue,
144 const uint32_t arrayInitTime,
145 std::chrono::milliseconds& libdbusArrayReadTime,
146 std::chrono::milliseconds& commonArrayApiReadTime) {
148 DBusMessage* libdbusMessage;
149 dbus_bool_t libdbusSuccess;
150 size_t libdbusInitElementCount = 0;
152 libdbusMessage = dbus_message_new_method_call("no.bus.here", "/no/object/here", NULL, "noMethodHere");
153 ASSERT_TRUE(libdbusMessage != NULL);
155 prepareLibdbusArray<_ArrayElementLibdbusType, _ArrayElementCommonApiType>(
157 arrayElementLibdbusType,
158 arrayElementLibdbusTypeAsString,
159 arrayInitElementValue,
161 libdbusInitElementCount);
163 measureLibdbusArrayReadTime<_ArrayElementLibdbusType, _ArrayElementCommonApiType>(
165 libdbusInitElementCount,
166 libdbusArrayReadTime);
168 measureCommonApiArrayReadTime<_ArrayElementLibdbusType, _ArrayElementCommonApiType>(
170 commonArrayApiReadTime,
171 libdbusInitElementCount);
175 TEST_F(BenchmarkingTest, InputStreamReadsIntegerArrayFasterThanLibdbus) {
176 std::chrono::milliseconds libdbusArrayReadTime;
177 std::chrono::milliseconds commonApiArrayReadTime;
179 measureArrayReadTime<int32_t, int32_t>(DBUS_TYPE_INT32,
180 DBUS_TYPE_INT32_AS_STRING,
183 libdbusArrayReadTime,
184 commonApiArrayReadTime);
186 RecordProperty("LibdbusArrayReadTime", libdbusArrayReadTime.count());
187 RecordProperty("CommonApiArrayReadTime", commonApiArrayReadTime.count());
189 std::cout << "LibdbusArrayReadTime = " << libdbusArrayReadTime.count() << std::endl;
190 std::cout << "CommonApiArrayReadTime = " << commonApiArrayReadTime.count() << std::endl;
192 ASSERT_LT(commonApiArrayReadTime.count(), libdbusArrayReadTime.count() * 0.30)
193 << "CommonAPI::DBus::DBusInputStream must be at least 70% faster than libdbus!";
196 TEST_F(BenchmarkingTest, InputStreamReadsStringArrayFasterThanLibdbus) {
197 std::chrono::milliseconds libdbusArrayReadTime;
198 std::chrono::milliseconds commonApiArrayReadTime;
200 measureArrayReadTime<char*, std::string>(DBUS_TYPE_STRING,
201 DBUS_TYPE_STRING_AS_STRING,
202 const_cast<char*>("01234567890123456789"),
204 libdbusArrayReadTime,
205 commonApiArrayReadTime);
207 RecordProperty("LibdbusArrayReadTime", libdbusArrayReadTime.count());
208 RecordProperty("CommonApiArrayReadTime", commonApiArrayReadTime.count());
210 std::cout << "LibdbusArrayReadTime = " << libdbusArrayReadTime.count() << std::endl;
211 std::cout << "CommonApiArrayReadTime = " << commonApiArrayReadTime.count() << std::endl;
213 ASSERT_LT(commonApiArrayReadTime.count(), libdbusArrayReadTime.count() * 0.30)
214 << "CommonAPI::DBus::DBusInputStream must be at least 70% faster than libdbus!";
217 int main(int argc, char** argv) {
218 ::testing::InitGoogleTest(&argc, argv);
219 return RUN_ALL_TESTS();