aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog1
-rw-r--r--src/writer.c16
2 files changed, 17 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index f2d7a14d..e18d37f0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -5,6 +5,7 @@ serd (UNRELEASED) unstable; urgency=low
* Tolerate invalid characters in string literals by replacing with the
Unicode replacement character
* Report reason for failure to open file in serdi
+ * Improve write performance by doing bulk writes for unescaped substrings
-- David Robillard <d@drobilla.net> (UNRELEASED)
diff --git a/src/writer.c b/src/writer.c
index a3cb5eab..8ab533d4 100644
--- a/src/writer.c
+++ b/src/writer.c
@@ -69,6 +69,22 @@ write_text(SerdWriter* writer, TextContext ctx,
{
char escape[11] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
for (size_t i = 0; i < n_bytes;) {
+ // Fast bulk write for long strings of printable ASCII
+ size_t j = i;
+ for (; j < n_bytes; ++j) {
+ if (utf8[j] == terminator || utf8[j] == '\\'
+ || (((writer->style & SERD_STYLE_ASCII) || ctx == WRITE_URI)
+ && !in_range(utf8[j], 0x20, 0x7E))) {
+ break;
+ }
+ }
+
+ if (j > i) {
+ writer->sink(&utf8[i], j - i, writer->stream);
+ i = j;
+ continue;
+ }
+
uint8_t in = utf8[i++];
if (ctx == WRITE_LONG_STRING) {
if (in == '\\') {