message Image {
required string uri = 1; //url to the thumbnail
optional string title = 2; //used in the html ALT
required int32 width = 3; // of the image
required int32 height = 4; // of the image
enum Size {
SMALL = 0;
LARGE = 1;
}
required Size size = 5; // of the image (in relative terms, provided by cnbc for example)
}
message Media {
required string uri = 1; //uri to the video, may not be an actual URL
optional string title = 2; //used in the html ALT
required int32 width = 3; // of the video
required int32 height = 4; // of the video
required string format = 5; //avi, jpg, youtube, cnbc, audio/mpeg formats ...
required int64 duration = 6; //time in miliseconds
required int64 size = 7; //file size
optional int32 bitrate = 8; //video
repeated string person = 9; //name of a person featured in the video
enum Player {
JAVA = 0;
FLASH = 1;
}
required Player player = 10; //in case of a player specific media
optional string copyright = 11;//media copyright
}
message MediaContent {
repeated Image image = 1;
required Media media = 2;
}
无论怎么去构造 small/medium/large 的输入,benchmark 仍然是存在特定倾向性的。而且这种倾向性是不明确的。比如 medium 的输入,到底说明了什么?medium 对于不同的人来说,可能意味着完全不同的东西。所以,在这里我想改变一下游戏的规则。不去选择一个所谓的最现实的配比,而是构造一些极端的情况。这样,我们可以一目了然的知道,JSON的强项和弱点都是什么。通过把这些缺陷放大出来,我们也就可以对最坏的情况有一个清晰的预期。具体在你的场景下性能差距是怎样的一个区间内,也可以大概预估出来。
private static int parsePositiveInt(final byte[] buf, final JsonReader reader, final int start, final int end, int i) throws IOException {
int value = 0;
for (; i < end; i++) {
final int ind = buf[i] - 48;
if (ind < 0 || ind > 9) {
... // abbreviated
}
value = (value << 3) + (value << 1) + ind;
if (value < 0) {
throw new IOException("Integer overflow detected at position: " + reader.positionInStream(end - start));
}
}
return value;
}
private static double parsePositiveDouble(final byte[] buf, final JsonReader reader, final int start, final int end, int i) throws IOException {
long value = 0;
byte ch = ' ';
for (; i < end; i++) {
ch = buf[i];
if (ch == '.') break;
final int ind = buf[i] - 48;
value = (value << 3) + (value << 1) + ind;
if (ind < 0 || ind > 9) {
return parseDoubleGeneric(reader.prepareBuffer(start), end - start, reader);
}
}
if (i == end) return value;
else if (ch == '.') {
i++;
long div = 1;
for (; i < end; i++) {
final int ind = buf[i] - 48;
div = (div << 3) + (div << 1);
value = (value << 3) + (value << 1) + ind;
if (ind < 0 || ind > 9) {
return parseDoubleGeneric(reader.prepareBuffer(start), end - start, reader);
}
}
return value / (double) div;
}
return value;
}
浮点数被去掉了点,存成了 long 类型,然后再除以对应的10的倍数。如果输入是3.1415,则会变成 31415/10000。
从对象的编解码的 benchmark 结果可以看出,Protobuf 在这个方面仅仅比 Jackson 略微强一些,而比 DSL-Json 要慢。
10、整形列表解码性能测试(Decode Integer List)
Protobuf 对于整数列表有特别的支持,可以打包存储:
22 // tag (field number 4, wire type 2)
06 // payload size (6 bytes)
03 // first element (varint 3)
8E 02 // second element (varint 270)
9E A7 05 // third element (varint 86942)
设置 [packed=true]
message PbTestObject {
repeated int32 field1 = 1 [packed=true];
}
for (int i = 0; i < chars.length; i++) {
bb = buffer[ci++];
if (bb == '"') {
currentIndex = ci;
return i;
}
// If we encounter a backslash, which is a beginning of an escape sequence
// or a high bit was set - indicating an UTF-8 encoded multibyte character,
// there is no chance that we can decode the string without instantiating
// a temporary buffer, so quit this loop
if ((bb ^ '\\') < 1) break;
chars[i] = (char) bb;
}