aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWouter van Oortmerssen <aardappel@gmail.com>2017-01-27 11:26:35 -0800
committerWouter van Oortmerssen <aardappel@gmail.com>2017-01-27 11:26:35 -0800
commit87e29b25def0159ac3d6607595643c2131d7b811 (patch)
tree429dd6de84dca796d683b84305536ae575725bbc
parent3dee617c8633823fb550e24ef7a20f602cad6355 (diff)
downloadflatbuffers-87e29b25def0159ac3d6607595643c2131d7b811.tar.gz
Some small speed optimizations to the core copying functions.
Change-Id: Id8c1afb84f4ab0e2edca4290e3de5589fa06e578 Tested: on Linux.
-rw-r--r--include/flatbuffers/flatbuffers.h26
-rw-r--r--samples/monster_generated.h4
-rw-r--r--tests/monster_test_generated.h4
3 files changed, 23 insertions, 11 deletions
diff --git a/include/flatbuffers/flatbuffers.h b/include/flatbuffers/flatbuffers.h
index 1d979cc3..d1520f5c 100644
--- a/include/flatbuffers/flatbuffers.h
+++ b/include/flatbuffers/flatbuffers.h
@@ -560,18 +560,30 @@ class vector_downward {
uint8_t *data_at(size_t offset) const { return buf_ + reserved_ - offset; }
- // push() & fill() are most frequently called with small byte counts (<= 4),
- // which is why we're using loops rather than calling memcpy/memset.
void push(const uint8_t *bytes, size_t num) {
auto dest = make_space(num);
- for (size_t i = 0; i < num; i++) dest[i] = bytes[i];
+ memcpy(dest, bytes, num);
}
+ // Specialized version of push() that avoids memcpy call for small data.
+ template<typename T> void push_small(T little_endian_t) {
+ auto dest = make_space(sizeof(T));
+ *reinterpret_cast<T *>(dest) = little_endian_t;
+ }
+
+ // fill() is most frequently called with small byte counts (<= 4),
+ // which is why we're using loops rather than calling memset.
void fill(size_t zero_pad_bytes) {
auto dest = make_space(zero_pad_bytes);
for (size_t i = 0; i < zero_pad_bytes; i++) dest[i] = 0;
}
+ // Version for when we know the size is larger.
+ void fill_big(size_t zero_pad_bytes) {
+ auto dest = make_space(zero_pad_bytes);
+ memset(dest, 0, zero_pad_bytes);
+ }
+
void pop(size_t bytes_to_remove) { cur_ += bytes_to_remove; }
private:
@@ -762,7 +774,7 @@ FLATBUFFERS_FINAL_CLASS
AssertScalarT<T>();
T litle_endian_element = EndianScalar(element);
Align(sizeof(T));
- PushBytes(reinterpret_cast<uint8_t *>(&litle_endian_element), sizeof(T));
+ buf_.push_small(litle_endian_element);
return GetSize();
}
@@ -794,7 +806,7 @@ FLATBUFFERS_FINAL_CLASS
template<typename T> void AddStruct(voffset_t field, const T *structptr) {
if (!structptr) return; // Default, don't store.
Align(AlignOf<T>());
- PushBytes(reinterpret_cast<const uint8_t *>(structptr), sizeof(T));
+ buf_.push_small(*structptr);
TrackField(field, GetSize());
}
@@ -845,7 +857,7 @@ FLATBUFFERS_FINAL_CLASS
// Write a vtable, which consists entirely of voffset_t elements.
// It starts with the number of offsets, followed by a type id, followed
// by the offsets themselves. In reverse:
- buf_.fill(numfields * sizeof(voffset_t));
+ buf_.fill_big(numfields * sizeof(voffset_t));
auto table_object_size = vtableoffsetloc - start;
assert(table_object_size < 0x10000); // Vtable use 16bit offsets.
PushElement<voffset_t>(static_cast<voffset_t>(table_object_size));
@@ -1239,7 +1251,7 @@ FLATBUFFERS_FINAL_CLASS
minalign_);
if (file_identifier) {
assert(strlen(file_identifier) == kFileIdentifierLength);
- buf_.push(reinterpret_cast<const uint8_t *>(file_identifier),
+ PushBytes(reinterpret_cast<const uint8_t *>(file_identifier),
kFileIdentifierLength);
}
PushElement(ReferTo(root)); // Location of root.
diff --git a/samples/monster_generated.h b/samples/monster_generated.h
index 0cf21f7b..61167e43 100644
--- a/samples/monster_generated.h
+++ b/samples/monster_generated.h
@@ -515,8 +515,8 @@ inline bool VerifyEquipmentVector(flatbuffers::Verifier &verifier, const flatbuf
if (values->size() != types->size()) return false;
for (flatbuffers::uoffset_t i = 0; i < values->size(); ++i) {
if (!VerifyEquipment(
- verifier, values->Get(i), types->GetEnum<Equipment>(i))) {
- return false;
+ verifier, values->Get(i), types->GetEnum<Equipment>(i))) {
+ return false;
}
}
return true;
diff --git a/tests/monster_test_generated.h b/tests/monster_test_generated.h
index b96f85e8..69780498 100644
--- a/tests/monster_test_generated.h
+++ b/tests/monster_test_generated.h
@@ -1203,8 +1203,8 @@ inline bool VerifyAnyVector(flatbuffers::Verifier &verifier, const flatbuffers::
if (values->size() != types->size()) return false;
for (flatbuffers::uoffset_t i = 0; i < values->size(); ++i) {
if (!VerifyAny(
- verifier, values->Get(i), types->GetEnum<Any>(i))) {
- return false;
+ verifier, values->Get(i), types->GetEnum<Any>(i))) {
+ return false;
}
}
return true;