Skip to content

Commit 72a1afc

Browse files
committed
Using std::vector::assign in stead of resize + memcpy
Because std::vector::resize adds an unnecessary initialization step this performs worse than using assign Signed-off-by: Martijn Reicher <[email protected]>
1 parent af5e2af commit 72a1afc

File tree

2 files changed

+63
-15
lines changed

2 files changed

+63
-15
lines changed

src/ddscxx/include/org/eclipse/cyclonedds/core/cdr/cdr_stream.hpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -971,6 +971,39 @@ bool max_string(S& str, const T& max_sz, size_t N)
971971
return true;
972972
}
973973

974+
/**
975+
* @brief
976+
* Sequence of base types read function.
977+
*
978+
* This is called when a resize + memcpy is way less efficient than an assign,
979+
* as this skips the default initialization of entities in the sequence.
980+
*
981+
* @param[in, out] str The stream being read from.
982+
* @param[in] toread The sequence being read into.
983+
* @param[in] N Number of base entities to read.
984+
*
985+
* @return Whether the operation was completed succesfully.
986+
*/
987+
template<typename S, template<typename,typename> class V, typename T, typename A, std::enable_if_t<std::is_base_of<cdr_stream, S>::value && std::is_arithmetic<T>::value && !std::is_same<T,bool>::value, bool> = true >
988+
bool read(S& str, V<T,A> &toread, size_t N)
989+
{
990+
if (str.position() == SIZE_MAX
991+
|| !str.align(sizeof(T), false)
992+
|| !str.bytes_available(sizeof(T)*N))
993+
return false;
994+
995+
auto ptr = reinterpret_cast<const T*>(str.get_cursor());
996+
toread.assign(ptr, ptr+N);
997+
str.incr_position(N*sizeof(T));
998+
999+
if (str.swap_endianness()) {
1000+
for (auto &e:toread)
1001+
byte_swap(e);
1002+
}
1003+
1004+
return true;
1005+
}
1006+
9741007
}
9751008
}
9761009
}

src/idlcxx/src/streamers.c

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,8 @@ write_base_type_streaming_functions(
365365
const idl_type_spec_t* type_spec,
366366
const char* accessor,
367367
const char* read_accessor,
368-
instance_location_t loc)
368+
instance_location_t loc,
369+
bool skip_reads)
369370
{
370371
const char* fmt =
371372
" if (!{T}(streamer, %1$s))\n"
@@ -390,7 +391,7 @@ write_base_type_streaming_functions(
390391
}
391392

392393
if (multi_putf(streams, CONST, fmt, accessor)
393-
|| multi_putf(streams, READ, rfmt, read_accessor))
394+
|| (!skip_reads && multi_putf(streams, READ, rfmt, read_accessor)))
394395
return IDL_RETCODE_NO_MEMORY;
395396

396397
return IDL_RETCODE_OK;
@@ -402,24 +403,25 @@ write_streaming_functions(
402403
const idl_type_spec_t* type_spec,
403404
const char* accessor,
404405
const char* read_accessor,
405-
instance_location_t loc)
406+
instance_location_t loc,
407+
bool skip_reads)
406408
{
407409
if (idl_is_alias(type_spec)) {
408410
const idl_typedef_t *td = idl_parent(type_spec);
409411
const idl_type_spec_t *ts = idl_type_spec(td);
410412
//if this is an alias for a bare type, just use the bare type
411413
if (!idl_is_array(td->declarators) && !idl_is_sequence(ts) && (idl_is_base_type(ts) || idl_is_string(ts)))
412-
return write_streaming_functions(streams, ts, accessor, read_accessor, loc);
414+
return write_streaming_functions(streams, ts, accessor, read_accessor, loc, skip_reads);
413415
else
414416
return write_typedef_streaming_functions(streams, type_spec, accessor, read_accessor);
415417
} else if (idl_is_forward(type_spec)) {
416-
return write_streaming_functions(streams, idl_type_spec(type_spec), accessor, read_accessor, loc);
418+
return write_streaming_functions(streams, idl_type_spec(type_spec), accessor, read_accessor, loc, skip_reads);
417419
} else if (idl_is_string(type_spec)) {
418420
return write_string_streaming_functions(streams, type_spec, accessor, read_accessor);
419421
} else if (idl_is_union(type_spec) || idl_is_struct(type_spec)) {
420422
return write_constructed_type_streaming_functions(streams, accessor, read_accessor);
421423
} else {
422-
return write_base_type_streaming_functions(streams, type_spec, accessor, read_accessor, loc);
424+
return write_base_type_streaming_functions(streams, type_spec, accessor, read_accessor, loc, skip_reads);
423425
}
424426
}
425427

@@ -439,7 +441,8 @@ sequence_writes(const idl_pstate_t* pstate,
439441
size_t depth,
440442
const char* accessor,
441443
const char* read_accessor,
442-
instance_location_t loc)
444+
instance_location_t loc,
445+
bool skip_reads)
443446
{
444447
const idl_type_spec_t *type_spec = seq->type_spec;
445448

@@ -457,7 +460,7 @@ sequence_writes(const idl_pstate_t* pstate,
457460
if (IDL_PRINTA(&type, get_cpp11_type, type_spec, streams->generator) < 0
458461
|| multi_putf(streams, MOVE | MAX, mfmt, type, depth)
459462
|| multi_putf(streams, WRITE, sfmt, accessor, depth)
460-
|| multi_putf(streams, READ, sfmt, read_accessor, depth))
463+
|| (!skip_reads && multi_putf(streams, READ, sfmt, read_accessor, depth)))
461464
return IDL_RETCODE_NO_MEMORY;
462465

463466
return IDL_RETCODE_OK;
@@ -483,7 +486,7 @@ sequence_writes(const idl_pstate_t* pstate,
483486
if (unroll_sequence (pstate, streams, (idl_sequence_t*)type_spec, depth + 1, new_accessor, new_read_accessor, loc))
484487
return IDL_RETCODE_NO_MEMORY;
485488
} else {
486-
if (write_streaming_functions (streams, type_spec, new_accessor, new_read_accessor, loc))
489+
if (write_streaming_functions (streams, type_spec, new_accessor, new_read_accessor, loc, skip_reads))
487490
return IDL_RETCODE_NO_MEMORY;
488491
}
489492

@@ -513,7 +516,7 @@ unroll_sequence(const idl_pstate_t* pstate,
513516
" return false;\n";
514517
static const char* fmt1 =
515518
" {\n"
516-
" uint32_t se_%1$u = uint32_t(%2$s.size());\n";
519+
" uint32_t se_%1$u(static_cast<uint32_t>(%2$s.size()));\n";
517520
static const char* length_check =
518521
" if (se_%1$u > %2$u &&\n"
519522
" streamer.status(serialization_status::{T}_bound_exceeded))\n"
@@ -523,23 +526,35 @@ unroll_sequence(const idl_pstate_t* pstate,
523526
" return false;\n";
524527
static const char* rfmt =
525528
" %1$s.resize(se_%2$u);\n";
529+
static const char* rfmt2 =
530+
" if (!read(streamer,%1$s,se_%2$u))\n"
531+
" return false;\n";
526532
static const char* mfmt =
527533
" {\n"
528534
" uint32_t se_%1$u = %2$u;\n";
535+
static const char* rfmt3 =
536+
" {\n"
537+
" uint32_t se_%1$u(0);\n";
529538

530539
const idl_type_spec_t *root_type_spec = idl_strip(seq->type_spec, IDL_STRIP_ALIASES | IDL_STRIP_FORWARD);
531540
if (multi_putf(streams, ALL, consec_start_fmt, idl_is_base_type(root_type_spec) && !idl_is_array(root_type_spec) ? "true" : "false"))
532541
return IDL_RETCODE_NO_MEMORY;
533542

534-
if (multi_putf(streams, READ, fmt1, depth, read_accessor)
543+
bool skip_reads = !idl_is_sequence(seq->type_spec) && idl_is_base_type(root_type_spec) && !(idl_mask(root_type_spec) == IDL_BOOL);
544+
545+
if (multi_putf(streams, READ, rfmt3, depth)
535546
|| multi_putf(streams, (WRITE | MOVE), fmt1, depth, accessor)
536547
|| multi_putf(streams, MAX, mfmt, depth, maximum)
537-
|| (maximum && multi_putf(streams, NOMAX, length_check, depth, maximum))
538548
|| multi_putf(streams, ALL, fmt2, depth)
539-
|| multi_putf(streams, READ, rfmt, read_accessor, depth))
549+
|| (maximum && multi_putf(streams, NOMAX, length_check, depth, maximum)))
550+
return IDL_RETCODE_NO_MEMORY;
551+
552+
if (!skip_reads && multi_putf(streams, READ, rfmt, read_accessor, depth))
553+
return IDL_RETCODE_NO_MEMORY;
554+
else if (skip_reads && multi_putf(streams, READ, rfmt2, read_accessor, depth))
540555
return IDL_RETCODE_NO_MEMORY;
541556

542-
if (sequence_writes(pstate, streams, seq, depth, accessor, read_accessor, loc))
557+
if (sequence_writes(pstate, streams, seq, depth, accessor, read_accessor, loc, skip_reads))
543558
return IDL_RETCODE_NO_MEMORY;
544559

545560
//close sequence
@@ -655,7 +670,7 @@ process_entity(
655670
if (unroll_sequence(pstate, streams, (idl_sequence_t*)type_spec, 1, accessor, read_accessor, loc))
656671
return IDL_RETCODE_NO_MEMORY;
657672
} else {
658-
if (write_streaming_functions(streams, type_spec, accessor, read_accessor, loc))
673+
if (write_streaming_functions(streams, type_spec, accessor, read_accessor, loc, false))
659674
return IDL_RETCODE_NO_MEMORY;
660675
}
661676

0 commit comments

Comments
 (0)