Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions msgpack-core/src/main/java/org/msgpack/core/MessagePack.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ public static class Config
private final int stringEncoderBufferSize;
private final int stringDecoderBufferSize;
private final int packerBufferSize;
private final int packerSmallStringOptimizationThreshold; // This parameter is subject to change
private final int packerRawDataCopyingThreshold;

public Config(
Expand All @@ -61,6 +62,7 @@ public Config(
int stringEncoderBufferSize,
int stringDecoderBufferSize,
int packerBufferSize,
int packerSmallStringOptimizationThreshold,
int packerRawDataCopyingThreshold)
{
checkArgument(packerBufferSize > 0, "packer buffer size must be larger than 0: " + packerBufferSize);
Expand All @@ -75,6 +77,7 @@ public Config(
this.stringEncoderBufferSize = stringEncoderBufferSize;
this.stringDecoderBufferSize = stringDecoderBufferSize;
this.packerBufferSize = packerBufferSize;
this.packerSmallStringOptimizationThreshold = packerSmallStringOptimizationThreshold;
this.packerRawDataCopyingThreshold = packerRawDataCopyingThreshold;
}

Expand Down Expand Up @@ -133,6 +136,11 @@ public int getPackerBufferSize()
return packerBufferSize;
}

public int getPackerSmallStringOptimizationThreshold()
{
return packerSmallStringOptimizationThreshold;
}

public int getPackerRawDataCopyingThreshold()
{
return packerRawDataCopyingThreshold;
Expand All @@ -154,6 +162,7 @@ public static class ConfigBuilder
private int stringEncoderBufferSize = 8192;
private int stringDecoderBufferSize = 8192;
private int packerBufferSize = 8192;
private int packerSmallStringOptimizationThreshold = 512; // This parameter is subject to change
private int packerRawDataCopyingThreshold = 512;

public Config build()
Expand All @@ -167,6 +176,7 @@ public Config build()
stringEncoderBufferSize,
stringDecoderBufferSize,
packerBufferSize,
packerSmallStringOptimizationThreshold,
packerRawDataCopyingThreshold
);
}
Expand Down Expand Up @@ -219,6 +229,12 @@ public ConfigBuilder packerBufferSize(int size)
return this;
}

public ConfigBuilder packerSmallStringOptimizationThreshold(int threshold)
{
this.packerSmallStringOptimizationThreshold = threshold;
return this;
}

public ConfigBuilder packerRawDataCopyingThreshold(int threshold)
{
this.packerRawDataCopyingThreshold = threshold;
Expand Down
14 changes: 14 additions & 0 deletions msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,14 @@ public MessagePacker packDouble(double v)
return this;
}

private void packSmallString(String s)
throws IOException
{
byte[] bytes = s.getBytes(MessagePack.UTF8);
packRawStringHeader(bytes.length);
writePayload(bytes);
}

/**
* Pack the input String in UTF-8 encoding
*
Expand All @@ -457,6 +465,12 @@ public MessagePacker packString(String s)
return this;
}

if (s.length() < config.getPackerSmallStringOptimizationThreshold()) {
// Write the length and payload of small string to the buffer so that it avoids an extra flush of buffer
packSmallString(s);
return this;
}

CharBuffer in = CharBuffer.wrap(s);
prepareEncoder();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,32 @@ class MessagePackerTest
up1.hasNext shouldBe false
up1.close
}

"pack a lot of String within expected time" in {
val count = 20000

def measureDuration(outputStream: java.io.OutputStream) = {
val packer = MessagePack.newDefaultPacker(outputStream)
var i = 0
while (i < count) {
packer.packString("0123456789ABCDEF")
i += 1
}
packer.close
}

val t = time("packString into OutputStream", repeat = 10) {
block("byte-array-output-stream") {
measureDuration(new ByteArrayOutputStream())
}

block("file-output-stream") {
val (_, fileOutput) = createTempFileWithOutputStream
measureDuration(fileOutput)
}
}
t("file-output-stream").averageWithoutMinMax shouldBe < (t("byte-array-output-stream").averageWithoutMinMax * 4)
}
}

"compute totalWrittenBytes" in {
Expand Down