Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
P
protobuf
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
protobuf
Commits
daee0516
Commit
daee0516
authored
Feb 01, 2010
by
kenton@google.com
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Optimize Java string serialization. Patch from Evan Jones.
parent
ab6950d7
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
99 additions
and
9 deletions
+99
-9
CHANGES.txt
CHANGES.txt
+5
-0
CONTRIBUTORS.txt
CONTRIBUTORS.txt
+2
-0
CodedOutputStream.java
.../src/main/java/com/google/protobuf/CodedOutputStream.java
+17
-0
CodedOutputStreamTest.java
.../test/java/com/google/protobuf/CodedOutputStreamTest.java
+24
-0
java_primitive_field.cc
src/google/protobuf/compiler/java/java_primitive_field.cc
+49
-9
java_primitive_field.h
src/google/protobuf/compiler/java/java_primitive_field.h
+2
-0
No files found.
CHANGES.txt
View file @
daee0516
????-??-?? version 2.3.1:
Java
* Improved performance of string serialization.
2010-01-08 version 2.3.0:
2010-01-08 version 2.3.0:
General
General
...
...
CONTRIBUTORS.txt
View file @
daee0516
...
@@ -80,6 +80,8 @@ Patch contributors:
...
@@ -80,6 +80,8 @@ Patch contributors:
* Fixes for Solaris 10 32/64-bit confusion.
* Fixes for Solaris 10 32/64-bit confusion.
Evan Jones <evanj@mit.edu>
Evan Jones <evanj@mit.edu>
* Optimize Java serialization code when writing a small message to a stream.
* Optimize Java serialization code when writing a small message to a stream.
* Optimize Java serialization of strings so that UTF-8 encoding happens only
once per string per serialization call.
* Clean up some Java warnings.
* Clean up some Java warnings.
Michael Kucharski <m.kucharski@gmail.com>
Michael Kucharski <m.kucharski@gmail.com>
* Added CodedInputStream.getTotalBytesRead().
* Added CodedInputStream.getTotalBytesRead().
java/src/main/java/com/google/protobuf/CodedOutputStream.java
View file @
daee0516
...
@@ -193,6 +193,23 @@ public final class CodedOutputStream {
...
@@ -193,6 +193,23 @@ public final class CodedOutputStream {
writeStringNoTag
(
value
);
writeStringNoTag
(
value
);
}
}
/**
* Write a {@code string} field, including tag, to the stream, where bytes
* is the encoded version of value. Used by the SPEED version of messages
* to avoid performing the UTF-8 conversion twice. bytes is simply a hint
* and may be null. If it is null, value will be converted as usual.
*/
public
void
writeStringCached
(
final
int
fieldNumber
,
final
String
value
,
ByteString
bytes
)
throws
IOException
{
// The cache can be null if serializing without getting the size first, or
// if there are multiple threads.
if
(
bytes
==
null
)
{
bytes
=
ByteString
.
copyFromUtf8
(
value
);
}
writeBytes
(
fieldNumber
,
bytes
);
}
/** Write a {@code group} field, including tag, to the stream. */
/** Write a {@code group} field, including tag, to the stream. */
public
void
writeGroup
(
final
int
fieldNumber
,
final
MessageLite
value
)
public
void
writeGroup
(
final
int
fieldNumber
,
final
MessageLite
value
)
throws
IOException
{
throws
IOException
{
...
...
java/src/test/java/com/google/protobuf/CodedOutputStreamTest.java
View file @
daee0516
...
@@ -36,6 +36,7 @@ import protobuf_unittest.UnittestProto.TestPackedTypes;
...
@@ -36,6 +36,7 @@ import protobuf_unittest.UnittestProto.TestPackedTypes;
import
junit.framework.TestCase
;
import
junit.framework.TestCase
;
import
java.io.ByteArrayOutputStream
;
import
java.io.ByteArrayOutputStream
;
import
java.io.IOException
;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.List
;
...
@@ -211,6 +212,29 @@ public class CodedOutputStreamTest extends TestCase {
...
@@ -211,6 +212,29 @@ public class CodedOutputStreamTest extends TestCase {
0x9abcdef012345678
L
);
0x9abcdef012345678
L
);
}
}
/** Test writing cached strings. */
public
void
testWriteStringCached
()
throws
IOException
{
final
ByteArrayOutputStream
output
=
new
ByteArrayOutputStream
();
final
CodedOutputStream
stream
=
CodedOutputStream
.
newInstance
(
output
);
// Test writing a string that is not cached
stream
.
writeStringCached
(
5
,
"hello"
,
null
);
stream
.
flush
();
CodedInputStream
in
=
CodedInputStream
.
newInstance
(
output
.
toByteArray
());
assertEquals
(
WireFormat
.
makeTag
(
5
,
WireFormat
.
WIRETYPE_LENGTH_DELIMITED
),
in
.
readTag
());
assertEquals
(
"hello"
,
in
.
readString
());
// Write a cached string: the real string is ignored
output
.
reset
();
stream
.
writeStringCached
(
5
,
"ignored"
,
ByteString
.
copyFromUtf8
(
"hello"
));
stream
.
flush
();
in
=
CodedInputStream
.
newInstance
(
output
.
toByteArray
());
assertEquals
(
WireFormat
.
makeTag
(
5
,
WireFormat
.
WIRETYPE_LENGTH_DELIMITED
),
in
.
readTag
());
assertEquals
(
"hello"
,
in
.
readString
());
}
/** Test encodeZigZag32() and encodeZigZag64(). */
/** Test encodeZigZag32() and encodeZigZag64(). */
public
void
testEncodeZigZag
()
throws
Exception
{
public
void
testEncodeZigZag
()
throws
Exception
{
assertEquals
(
0
,
CodedOutputStream
.
encodeZigZag32
(
0
));
assertEquals
(
0
,
CodedOutputStream
.
encodeZigZag32
(
0
));
...
...
src/google/protobuf/compiler/java/java_primitive_field.cc
View file @
daee0516
...
@@ -199,6 +199,14 @@ GenerateMembers(io::Printer* printer) const {
...
@@ -199,6 +199,14 @@ GenerateMembers(io::Printer* printer) const {
"private $type$ $name$_ = $default$;
\n
"
"private $type$ $name$_ = $default$;
\n
"
"public boolean has$capitalized_name$() { return has$capitalized_name$; }
\n
"
"public boolean has$capitalized_name$() { return has$capitalized_name$; }
\n
"
"public $type$ get$capitalized_name$() { return $name$_; }
\n
"
);
"public $type$ get$capitalized_name$() { return $name$_; }
\n
"
);
// Avoid double encoding for Java strings
// This field does not need to be volatile because ByteString is immutable.
// http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html#finalRight
// However, it seems better to be safe than sorry.
if
(
ShouldUseStringEncodingCache
())
{
printer
->
Print
(
variables_
,
"private volatile com.google.protobuf.ByteString $name$EncodedCache_;
\n
"
);
}
}
}
void
PrimitiveFieldGenerator
::
void
PrimitiveFieldGenerator
::
...
@@ -259,25 +267,57 @@ GenerateParsingCode(io::Printer* printer) const {
...
@@ -259,25 +267,57 @@ GenerateParsingCode(io::Printer* printer) const {
void
PrimitiveFieldGenerator
::
void
PrimitiveFieldGenerator
::
GenerateSerializationCode
(
io
::
Printer
*
printer
)
const
{
GenerateSerializationCode
(
io
::
Printer
*
printer
)
const
{
printer
->
Print
(
variables_
,
if
(
ShouldUseStringEncodingCache
())
{
"if (has$capitalized_name$()) {
\n
"
// Pass the cached serialized version, then forget it.
" output.write$capitalized_type$($number$, get$capitalized_name$());
\n
"
// The cached version could be null if we didn't compute the size first,
"}
\n
"
);
// or if there are two threads attempting to serialize simultaneously.
// CodedOutputStream.writeStringCached handles this for us.
printer
->
Print
(
variables_
,
"if (has$capitalized_name$()) {
\n
"
" output.write$capitalized_type$Cached($number$,
\n
"
" get$capitalized_name$(),
\n
"
" $name$EncodedCache_);
\n
"
" $name$EncodedCache_ = null;
\n
"
"}
\n
"
);
}
else
{
printer
->
Print
(
variables_
,
"if (has$capitalized_name$()) {
\n
"
" output.write$capitalized_type$($number$, get$capitalized_name$());
\n
"
"}
\n
"
);
}
}
}
void
PrimitiveFieldGenerator
::
void
PrimitiveFieldGenerator
::
GenerateSerializedSizeCode
(
io
::
Printer
*
printer
)
const
{
GenerateSerializedSizeCode
(
io
::
Printer
*
printer
)
const
{
printer
->
Print
(
variables_
,
// Avoid double encoding for strings: serialize the string here
"if (has$capitalized_name$()) {
\n
"
if
(
ShouldUseStringEncodingCache
())
{
" size += com.google.protobuf.CodedOutputStream
\n
"
printer
->
Print
(
variables_
,
" .compute$capitalized_type$Size($number$, get$capitalized_name$());
\n
"
"if (has$capitalized_name$()) {
\n
"
"}
\n
"
);
" com.google.protobuf.ByteString serialized =
\n
"
" com.google.protobuf.ByteString.copyFromUtf8(
\n
"
" get$capitalized_name$());
\n
"
" $name$EncodedCache_ = serialized;
\n
"
" size += com.google.protobuf.CodedOutputStream
\n
"
" .computeBytesSize($number$, serialized);
\n
"
"}
\n
"
);
}
else
{
printer
->
Print
(
variables_
,
"if (has$capitalized_name$()) {
\n
"
" size += com.google.protobuf.CodedOutputStream
\n
"
" .compute$capitalized_type$Size($number$, get$capitalized_name$());
\n
"
"}
\n
"
);
}
}
}
string
PrimitiveFieldGenerator
::
GetBoxedType
()
const
{
string
PrimitiveFieldGenerator
::
GetBoxedType
()
const
{
return
BoxedPrimitiveTypeName
(
GetJavaType
(
descriptor_
));
return
BoxedPrimitiveTypeName
(
GetJavaType
(
descriptor_
));
}
}
bool
PrimitiveFieldGenerator
::
ShouldUseStringEncodingCache
()
const
{
return
GetType
(
descriptor_
)
==
FieldDescriptor
::
TYPE_STRING
&&
descriptor_
->
file
()
->
options
().
optimize_for
()
==
FileOptions
::
SPEED
;
}
// ===================================================================
// ===================================================================
RepeatedPrimitiveFieldGenerator
::
RepeatedPrimitiveFieldGenerator
::
...
...
src/google/protobuf/compiler/java/java_primitive_field.h
View file @
daee0516
...
@@ -62,6 +62,8 @@ class PrimitiveFieldGenerator : public FieldGenerator {
...
@@ -62,6 +62,8 @@ class PrimitiveFieldGenerator : public FieldGenerator {
string
GetBoxedType
()
const
;
string
GetBoxedType
()
const
;
private
:
private
:
bool
ShouldUseStringEncodingCache
()
const
;
const
FieldDescriptor
*
descriptor_
;
const
FieldDescriptor
*
descriptor_
;
map
<
string
,
string
>
variables_
;
map
<
string
,
string
>
variables_
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment