2
* Copyright (C) 2011 Akiban Technologies Inc.
3
* This program is free software: you can redistribute it and/or modify
4
* it under the terms of the GNU Affero General Public License, version 3,
5
* as published by the Free Software Foundation.
7
* This program is distributed in the hope that it will be useful,
8
* but WITHOUT ANY WARRANTY; without even the implied warranty of
9
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
* GNU Affero General Public License for more details.
12
* You should have received a copy of the GNU Affero General Public License
13
* along with this program. If not, see <http://www.gnu.org/licenses/>.
16
import java.util.Properties;
17
import java.util.Random;
19
import com.persistit.Exchange;
20
import com.persistit.Key;
21
import com.persistit.Value;
22
import com.persistit.Persistit;
26
* A simple demonstration of Persistit™'s insert and retrieval
27
* and performance. This class performs the following operations:
29
* <li> Initializes {@link com.persistit.Persistit} using stock properties file.
31
* <li> Creates an {@link com.persistit.Exchange} with which to store and fetch
32
* data to and from a tree.
34
* <li> Removes any data formerly stored in the tree.
36
* <li> Inserts numerous String values, indexed by
39
* <li> Traverses all keys in forward sequential order.
41
* <li> Traverses all keys in reverse sequential order.
43
* <li> Modifies records by random key value
45
* <li> Lengthens all records
47
* <li> Fetches records by random key value.
50
* By default, <tt>SimpleBench</tt> performs this cycle ten times, inserting
51
* 500,000 records. You can specify different iteration and cycle counts on the
55
* Note that if you run this program using a Sun HotSpot™
56
* Server JVM, you will observe a substantial performance improvement over
57
* multiple cycles as the optimizing compiler fully analyzes and optimizes
58
* heavily-used code paths.
63
public class SimpleBench
65
public static void main(String[] args)
71
w("This simple benchmark demonstrates Persistit's ability to");
72
w("modify its in-memory data structures fast. The buffer pool has");
73
w("been carefully sized to ensure that once the buffers are");
74
w("\"warmed up\", no disk I/O is needed to complete the store,");
75
w("traverse, and fetch operations being performed.");
77
w("Although real applications do not perform entirely in this");
78
w("manner, they typically do exhibit strong locality of reference");
79
w("within the keyspace, which is why disk caching is effective,");
80
w("and why it is important to examine in-memory performance.");
82
w("Truly meaningful performance comparisons can best be made by");
83
w("measuring actual application performance.");
86
// Initializes buffer pool, loads Volume(s)
87
// and sets up PrewriteJournal.
89
System.out.println("Initializing Persistit");
91
// Note: you can override datapath and logpath properties as follows:
93
// java -Dcom.persistit.datapath=... -Dcom.persistit.logpath=... SimpleBench
95
Properties props = new Properties();
96
props.setProperty("datapath", ".");
97
props.setProperty("logpath", ".");
98
props.setProperty("logfile", "${logpath}/persistit_${timestamp}.log");
99
props.setProperty("buffer.count.8192", "4K");
100
props.setProperty("volume.1",
101
"${datapath}/SimpleBench.v01,create,pageSize:8K," +
102
"initialSize:16M,extensionSize:1M,maximumSize:10G");
103
props.setProperty("pwjpath", "${datapath}/SimpleBench.pwj");
104
props.setProperty("pwjsize", "16M");
105
props.setProperty("pwjdelete", "true");
106
props.setProperty("pwjcount", "1");
108
Persistit persistit = new Persistit();
109
persistit.initialize(props);
113
doBench(persistit, args);
121
private static void w(String s)
123
System.out.println(s);
126
public static void doBench(Persistit persistit, String[] args)
130
// Source of random key values. Initialized with a constant seed
131
// value so that results are reproducible.
133
Random random = new Random(1);
135
// An Exchange provides all the methods you use to manipulate data.
136
// This constructs a Exchange in volume "SimpleBench" and either opens
137
// or creates within that volume a Tree called "BenchTree".
139
Exchange exchange = new Exchange(persistit, "SimpleBench", "BenchTree", true);
142
int iterations = 250000;
145
if (args.length > 0) iterations = Integer.parseInt(args[0]);
146
if (args.length > 1) cycles = Integer.parseInt(args[1]);
148
long time0 = System.currentTimeMillis();
149
for (int cycle = 1; cycle <= cycles; cycle++)
152
System.out.println();
153
System.out.println();
154
System.out.println("Starting cycle #" + cycle + " of " + cycles);
155
System.out.println();
157
// Remove all records everything.
159
exchange.removeAll();
161
// Set up a stock 30-character value to store.
163
exchange.getValue().putString("ABCDEFGHIJABCDEFGHIJABCDEFGHIJ");
166
// Inserts numerous String values, indexed by small integers.
169
"Inserting " + iterations +
170
" records in forward sequential key order ");
171
time = System.currentTimeMillis();
172
for (int index = 0; index < iterations; index++)
174
exchange.to(index).store();
175
if ((index % 50000) == 0) System.out.print(".");
177
time = System.currentTimeMillis() - time;
178
System.out.println(" -- took " + time + "ms");
182
// Traverses all keys in forward-sequential order.
185
"Traversing " + iterations +
186
" keys in forward order ");
187
exchange.to(Key.BEFORE);
188
time = System.currentTimeMillis();
189
for (int index = 0; exchange.next(); index++)
191
if ((index % 50000) == 0) System.out.print(".");
193
time = System.currentTimeMillis() - time;
194
System.out.println(" -- took " + time + "ms");
198
// Traverses all keys in reverse-sequential order.
201
"Traversing " + iterations +
202
" keys in reverse order ");
203
exchange.to(Key.AFTER);
204
time = System.currentTimeMillis();
205
for (int index = 0; exchange.previous(); index++)
207
if ((index % 50000) == 0) System.out.print(".");
209
time = System.currentTimeMillis() - time;
210
System.out.println(" -- took " + time + "ms");
214
// Updates numerous String values with equal length using random keys.
216
exchange.getValue().putString("abcdefghijabcdefghijabcdefghij");
219
"Modifying " + iterations +
220
" values by random key ");
221
time = System.currentTimeMillis();
222
for (int index = 0; index < iterations; index++)
224
if ((index % 50000) == 0) System.out.print(".");
225
int randomKeyInt = random.nextInt(iterations);
226
exchange.to(randomKeyInt).store();
228
time = System.currentTimeMillis() - time;
229
System.out.println(" -- took " + time + "ms");
233
// Lengthens all String values in forward-seqential key order.
235
exchange.getValue().putString("ABCDEFGHIJABCDEFGHIJABCDEFGHIJ0123456789");
238
"Lengthening " + iterations +
239
" values by 10 chars in forward-sequential order");
240
time = System.currentTimeMillis();
241
for (int index = 0; index < iterations; index++)
243
if ((index % 50000) == 0) System.out.print(".");
244
exchange.to(index).store();
246
time = System.currentTimeMillis() - time;
247
System.out.println(" -- took " + time + "ms");
250
// RETRIEVE ALL VALUES IN PSEUDO-RANDOM ORDER
252
StringBuilder sb = new StringBuilder();
254
"Retrieving " + iterations +
255
" values in random order");
256
time = System.currentTimeMillis();
257
for (int index = 0; index < iterations; index++)
259
if ((index % 50000) == 0) System.out.print(".");
261
int randomKeyInt = random.nextInt(iterations);
262
exchange.to(randomKeyInt).fetch();
264
exchange.getValue().getString(sb).length();
265
if (sb.length() != 40)
267
throw new RuntimeException(
268
"Wrong value " + exchange.getValue() +
269
" at " + randomKeyInt);
272
time = System.currentTimeMillis() - time;
273
System.out.println(" -- took " + time + "ms");
275
System.out.print("Flushing all pending updates to the OS");
276
time = System.currentTimeMillis();
278
time = System.currentTimeMillis() - time;
279
System.out.println(" -- took " + time + "ms");
281
System.out.print("Synching all pending I/O to disk");
282
time = System.currentTimeMillis();
284
time = System.currentTimeMillis() - time;
285
System.out.println(" -- took " + time + "ms");
288
time0 = System.currentTimeMillis() - time0;
289
System.out.println("Total time: " + time0);