summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Mollekopf <chrigi_1@fastmail.fm>2015-04-07 12:50:07 +0200
committerChristian Mollekopf <chrigi_1@fastmail.fm>2015-04-07 12:50:07 +0200
commitc00d5fb305abff370f869dec0e9404f8a4a5646b (patch)
tree12794ff568d272e7326f6502727443e7928cd64c
parentb7873e621ef45badaa70e2d285998c486920df4a (diff)
downloadsink-c00d5fb305abff370f869dec0e9404f8a4a5646b.tar.gz
sink-c00d5fb305abff370f869dec0e9404f8a4a5646b.zip
Use memcpy to copy tables into vectors.
Ideally we wouldn't be copying at all, and somehow cast the table to a vector. Unfortunately I haven't figured out how to do that, and this solution at least gets us from 0.065 ms to 0.028 ms in testCreateCommand.
-rw-r--r--common/entitybuffer.cpp27
-rw-r--r--common/entitybuffer.h7
-rw-r--r--tests/CMakeLists.txt1
-rw-r--r--tests/dummyresourcebenchmark.cpp22
4 files changed, 46 insertions, 11 deletions
diff --git a/common/entitybuffer.cpp b/common/entitybuffer.cpp
index 5ba4afe..b555ac3 100644
--- a/common/entitybuffer.cpp
+++ b/common/entitybuffer.cpp
@@ -56,17 +56,24 @@ void EntityBuffer::extractResourceBuffer(void *dataValue, int dataSize, const st
56 } 56 }
57} 57}
58 58
59void EntityBuffer::assembleEntityBuffer(flatbuffers::FlatBufferBuilder &fbb, void const *metadataData, size_t metadataSize, void const *resourceData, size_t resourceSize, void const *localData, size_t localSize) 59flatbuffers::Offset<flatbuffers::Vector<uint8_t> > EntityBuffer::appendAsVector(flatbuffers::FlatBufferBuilder &fbb, void const *data, size_t size)
60{ 60{
61 auto metadata = fbb.CreateVector<uint8_t>(static_cast<uint8_t const*>(metadataData), metadataSize); 61 //Since we do memcpy trickery, this will only work on little endian
62 auto resource = fbb.CreateVector<uint8_t>(static_cast<uint8_t const*>(resourceData), resourceSize); 62 assert(FLATBUFFERS_LITTLEENDIAN);
63 auto local = fbb.CreateVector<uint8_t>(static_cast<uint8_t const*>(localData), localSize); 63 auto metadata = fbb.CreateUninitializedVector<uint8_t>(size);
64 auto builder = Akonadi2::EntityBuilder(fbb); 64 {
65 builder.add_metadata(metadata); 65 auto ptr = reinterpret_cast<flatbuffers::Vector<uint8_t> *>(fbb.GetBufferPointer())->Data();
66 builder.add_resource(resource); 66 std::memcpy((void*)ptr, data, size);
67 builder.add_local(local); 67 }
68 return metadata;
69}
68 70
69 auto buffer = builder.Finish(); 71void EntityBuffer::assembleEntityBuffer(flatbuffers::FlatBufferBuilder &fbb, void const *metadataData, size_t metadataSize, void const *resourceData, size_t resourceSize, void const *localData, size_t localSize)
70 Akonadi2::FinishEntityBuffer(fbb, buffer); 72{
73 auto metadata = appendAsVector(fbb, metadataData, metadataSize);
74 auto resource = appendAsVector(fbb, resourceData, resourceSize);
75 auto local = appendAsVector(fbb, localData, localSize);
76 auto entity = Akonadi2::CreateEntity(fbb, metadata, resource, local);
77 Akonadi2::FinishEntityBuffer(fbb, entity);
71} 78}
72 79
diff --git a/common/entitybuffer.h b/common/entitybuffer.h
index 097b450..f22c84e 100644
--- a/common/entitybuffer.h
+++ b/common/entitybuffer.h
@@ -15,7 +15,14 @@ public:
15 const Entity &entity(); 15 const Entity &entity();
16 16
17 static void extractResourceBuffer(void *dataValue, int dataSize, const std::function<void(const uint8_t *, size_t size)> &handler); 17 static void extractResourceBuffer(void *dataValue, int dataSize, const std::function<void(const uint8_t *, size_t size)> &handler);
18 /*
19 * TODO: Ideally we would be passing references to vectors in the same bufferbuilder, to avoid needlessly copying data.
20 * Unfortunately I couldn't find a way to cast a table to a vector<uint8_t> reference.
21 * We can't use union's either (which would allow to have a field that stores a selection of tables), as we don't want to modify
22 * the entity schema for each resource's buffers.
23 */
18 static void assembleEntityBuffer(flatbuffers::FlatBufferBuilder &fbb, void const *metadataData, size_t metadataSize, void const *resourceData, size_t resourceSize, void const *localData, size_t localSize); 24 static void assembleEntityBuffer(flatbuffers::FlatBufferBuilder &fbb, void const *metadataData, size_t metadataSize, void const *resourceData, size_t resourceSize, void const *localData, size_t localSize);
25 static flatbuffers::Offset<flatbuffers::Vector<uint8_t> > appendAsVector(flatbuffers::FlatBufferBuilder &fbb, void const *data, size_t size);
19 26
20private: 27private:
21 const Entity *mEntity; 28 const Entity *mEntity;
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 8257c8a..a38471f 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -2,6 +2,7 @@ add_subdirectory(hawd)
2 2
3set(CMAKE_AUTOMOC ON) 3set(CMAKE_AUTOMOC ON)
4include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}/hawd) 4include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}/hawd)
5include_directories (${CMAKE_CURRENT_BINARY_DIR}/../dummyresource)
5 6
6generate_flatbuffers(calendar) 7generate_flatbuffers(calendar)
7 8
diff --git a/tests/dummyresourcebenchmark.cpp b/tests/dummyresourcebenchmark.cpp
index 7375ff8..308a4e8 100644
--- a/tests/dummyresourcebenchmark.cpp
+++ b/tests/dummyresourcebenchmark.cpp
@@ -3,6 +3,7 @@
3#include <QString> 3#include <QString>
4 4
5#include "dummyresource/resourcefactory.h" 5#include "dummyresource/resourcefactory.h"
6#include "dummyresource/domainadaptor.h"
6#include "clientapi.h" 7#include "clientapi.h"
7#include "commands.h" 8#include "commands.h"
8#include "entitybuffer.h" 9#include "entitybuffer.h"
@@ -11,7 +12,6 @@
11#include "entity_generated.h" 12#include "entity_generated.h"
12#include "metadata_generated.h" 13#include "metadata_generated.h"
13#include "createentity_generated.h" 14#include "createentity_generated.h"
14#include "dummyresource/resourcefactory.h"
15 15
16static void removeFromDisk(const QString &name) 16static void removeFromDisk(const QString &name)
17{ 17{
@@ -144,6 +144,26 @@ private Q_SLOTS:
144 qDebug() << "Append to messagequeue " << appendTime; 144 qDebug() << "Append to messagequeue " << appendTime;
145 qDebug() << "All processed: " << allProcessedTime << "/sec " << num*1000/allProcessedTime; 145 qDebug() << "All processed: " << allProcessedTime << "/sec " << num*1000/allProcessedTime;
146 } 146 }
147 void testCreateCommand()
148 {
149 Akonadi2::Domain::Event event;
150
151 QBENCHMARK {
152 auto mFactory = new DummyEventAdaptorFactory;
153 static flatbuffers::FlatBufferBuilder entityFbb;
154 entityFbb.Clear();
155 mFactory->createBuffer(event, entityFbb);
156
157 static flatbuffers::FlatBufferBuilder fbb;
158 fbb.Clear();
159 //This is the resource buffer type and not the domain type
160 auto type = fbb.CreateString("event");
161 // auto delta = fbb.CreateVector<uint8_t>(entityFbb.GetBufferPointer(), entityFbb.GetSize());
162 auto delta = Akonadi2::EntityBuffer::appendAsVector(fbb, entityFbb.GetBufferPointer(), entityFbb.GetSize());
163 auto location = Akonadi2::Commands::CreateCreateEntity(fbb, type, delta);
164 Akonadi2::Commands::FinishCreateEntityBuffer(fbb, location);
165 }
166 }
147}; 167};
148 168
149QTEST_MAIN(DummyResourceBenchmark) 169QTEST_MAIN(DummyResourceBenchmark)