Skip to content

Commit bdace01

Browse files
committed
Improve performance benchmark a bit; add byte[]-taking variant for name-based variant
1 parent e1b2916 commit bdace01

File tree

5 files changed

+74
-22
lines changed

5 files changed

+74
-22
lines changed

pom.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
<artifactId>java-uuid-generator</artifactId>
1313
<packaging>bundle</packaging>
1414
<name>Java UUID Generator</name>
15-
<version>3.0.1-SNAPSHOT</version>
15+
<version>3.1.0-SNAPSHOT</version>
1616
<description>
1717
Java UUID Generator (JUG) is a Java library for generating
1818
Universally Unique IDentifiers, UUIDs (see http://en.wikipedia.org/wiki/UUID).

src/main/java/com/fasterxml/uuid/StringArgGenerator.java

+12-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,17 @@
1010
*/
1111
public abstract class StringArgGenerator extends UUIDGenerator
1212
{
13-
public abstract UUID generate(String arg);
13+
/**
14+
* Method for generating name-based UUIDs using specified name (serialized to
15+
* bytes using UTF-8 encoding)
16+
*/
17+
public abstract UUID generate(String name);
1418

19+
/**
20+
* Method for generating name-based UUIDs using specified byte-serialization
21+
* of name.
22+
*
23+
* @since 3.1
24+
*/
25+
public abstract UUID generate(byte[] nameBytes);
1526
}

src/main/java/com/fasterxml/uuid/impl/NameBasedGenerator.java

+15-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.fasterxml.uuid.impl;
22

3+
import java.nio.charset.Charset;
34
import java.security.MessageDigest;
45
import java.util.UUID;
56

@@ -18,6 +19,11 @@
1819
*/
1920
public class NameBasedGenerator extends StringArgGenerator
2021
{
22+
public final static Charset _utf8;
23+
static {
24+
_utf8 = Charset.forName("UTF-8");
25+
}
26+
2127
/**
2228
* Namespace used when name is a DNS name.
2329
*/
@@ -108,17 +114,24 @@ public NameBasedGenerator(UUID namespace, MessageDigest digester, UUIDType type)
108114
/* UUID generation
109115
/**********************************************************************
110116
*/
111-
117+
112118
@Override
113119
public UUID generate(String name)
120+
{
121+
// !!! TODO: 14-Oct-2010, tatu: can repurpose faster UTF-8 encoding from Jackson
122+
return generate(name.getBytes(_utf8));
123+
}
124+
125+
@Override
126+
public UUID generate(byte[] nameBytes)
114127
{
115128
byte[] digest;
116129
synchronized (_digester) {
117130
_digester.reset();
118131
if (_namespace != null) {
119132
_digester.update(UUIDUtil.asByteArray(_namespace));
120133
}
121-
_digester.update(name.getBytes());
134+
_digester.update(nameBytes);
122135
digest = _digester.digest();
123136
}
124137
return UUIDUtil.constructUUID(_type, digest);

src/main/java/com/fasterxml/uuid/impl/RandomBasedGenerator.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,7 @@ public class RandomBasedGenerator extends NoArgGenerator
4343
public RandomBasedGenerator(Random rnd)
4444
{
4545
if (rnd == null) {
46-
/*
47-
* Could be synchronized, but since side effects are trivial
46+
/* Could be synchronized, but since side effects are trivial
4847
* (ie. possibility of generating more than one SecureRandom,
4948
* of which all but one are dumped) let's not add synchronization
5049
* overhead.

src/main/java/test/MeasurePerformance.java

+45-16
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,31 @@
88
/**
99
* Simple micro-benchmark for evaluating performance of various UUID generation
1010
* techniques, including JDK's method as well as JUG's variants.
11+
*<p>
12+
* Notes: for name-based variant we will pass plain Strings, assuming this is the
13+
* most common use case; even though it is possible to also pass raw byte arrays.
14+
* JDK and Jug implementations have similar performance so this only changes
15+
* relative speeds of name- vs time-based variants.
1116
*
12-
* @since 3.0
17+
* @since 3.1
1318
*/
1419
public class MeasurePerformance
1520
{
1621
// Let's generate quarter million UUIDs per test
1722

1823
private static final int ROUNDS = 250;
1924
private static final int COUNT = 1000;
25+
26+
private final static UUID NAMESPACE = NameBasedGenerator.NAMESPACE_DNS;
27+
28+
// also: let's just use a single name for name-based, to avoid extra overhead:
29+
final String NAME = "http://www.cowtowncoder.com/blog/blog.html";
30+
final byte[] NAME_BYTES;
31+
32+
public MeasurePerformance() throws java.io.IOException
33+
{
34+
NAME_BYTES = NAME.getBytes("UTF-8");
35+
}
2036

2137
public void test() throws Exception
2238
{
@@ -27,19 +43,18 @@ public void test() throws Exception
2743
// can either use bogus address; or local one, no difference perf-wise
2844
EthernetAddress nic = EthernetAddress.fromInterface();
2945

30-
UUID namespaceForNamed = NameBasedGenerator.NAMESPACE_DNS;
31-
46+
// Whether to include namespace? Depends on whether we compare with JDK (which does not)
47+
// UUID namespaceForNamed = NAMESPACE;
48+
UUID namespaceForNamed = null;
49+
3250
final NoArgGenerator secureRandomGen = Generators.randomBasedGenerator();
3351
final NoArgGenerator utilRandomGen = Generators.randomBasedGenerator(new java.util.Random(123));
3452
final NoArgGenerator timeGen = Generators.timeBasedGenerator(nic);
3553
final StringArgGenerator nameGen = Generators.nameBasedGenerator(namespaceForNamed);
36-
37-
// also: let's just use a single name for name-based, to avoid extra overhead:
38-
final String NAME = "http://www.cowtowncoder.com/blog/blog.html";
3954

4055
while (true) {
4156
try { Thread.sleep(100L); } catch (InterruptedException ie) { }
42-
int round = (i++ % 5);
57+
int round = (i++ % 6);
4358

4459
long curr = System.currentTimeMillis();
4560
String msg;
@@ -48,28 +63,33 @@ public void test() throws Exception
4863
switch (round) {
4964

5065
case 0:
51-
msg = "JDK";
66+
msg = "JDK, random";
5267
testJDK(uuids, ROUNDS);
5368
break;
54-
69+
5570
case 1:
71+
msg = "JDK, name";
72+
testJDKNames(uuids, ROUNDS);
73+
break;
74+
75+
case 2:
5676
msg = "Jug, SecureRandom";
5777
testNoArgs(uuids, ROUNDS, secureRandomGen);
5878
break;
5979

60-
case 2:
80+
case 3:
6181
msg = "Jug, java.util.Random";
6282
testNoArgs(uuids, ROUNDS, utilRandomGen);
6383
break;
6484

65-
case 3:
85+
case 4:
6686
msg = "Jug, time-based";
6787
testNoArgs(uuids, ROUNDS, timeGen);
6888
break;
6989

70-
case 4:
90+
case 5:
7191
msg = "Jug, name-based";
72-
testStringArg(uuids, ROUNDS, nameGen, NAME);
92+
testStringArg(uuids, ROUNDS, nameGen);
7393
break;
7494

7595
default:
@@ -93,6 +113,16 @@ private final void testJDK(UUID[] uuids, int rounds)
93113
}
94114
}
95115

116+
private final void testJDKNames(UUID[] uuids, int rounds) throws java.io.IOException
117+
{
118+
while (--rounds >= 0) {
119+
for (int i = 0, len = uuids.length; i < len; ++i) {
120+
final byte[] nameBytes = NAME.getBytes("UTF-8");
121+
uuids[i] = UUID.nameUUIDFromBytes(nameBytes);
122+
}
123+
}
124+
}
125+
96126
private final void testNoArgs(UUID[] uuids, int rounds, NoArgGenerator uuidGen)
97127
{
98128
while (--rounds >= 0) {
@@ -102,12 +132,11 @@ private final void testNoArgs(UUID[] uuids, int rounds, NoArgGenerator uuidGen)
102132
}
103133
}
104134

105-
private final void testStringArg(UUID[] uuids, int rounds, StringArgGenerator uuidGen,
106-
String name)
135+
private final void testStringArg(UUID[] uuids, int rounds, StringArgGenerator uuidGen)
107136
{
108137
while (--rounds >= 0) {
109138
for (int i = 0, len = uuids.length; i < len; ++i) {
110-
uuids[i] = uuidGen.generate(name);
139+
uuids[i] = uuidGen.generate(NAME);
111140
}
112141
}
113142
}

0 commit comments

Comments
 (0)