some more micro bench support

This commit is contained in:
kimchy 2011-03-30 23:32:33 +02:00
parent dc0e493cce
commit f90b4e6fee
3 changed files with 510 additions and 16 deletions

View File

@ -25,14 +25,14 @@ import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.Requests;
import org.elasticsearch.client.action.bulk.BulkRequestBuilder;
import org.elasticsearch.common.RandomStringGenerator;
import org.elasticsearch.common.StopWatch;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.SizeValue;
import org.elasticsearch.common.util.concurrent.jsr166y.ThreadLocalRandom;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.node.Node;
import java.io.IOException;
import static org.elasticsearch.client.Requests.*;
import static org.elasticsearch.cluster.metadata.IndexMetaData.*;
import static org.elasticsearch.common.settings.ImmutableSettings.*;
@ -48,10 +48,10 @@ public class TermsFacetSearchBenchmark {
public static void main(String[] args) throws Exception {
Settings settings = settingsBuilder()
.put("index.engine.robin.refreshInterval", "-1")
.put("index.refresh_interval", "-1")
.put("gateway.type", "local")
.put(SETTING_NUMBER_OF_SHARDS, 2)
.put(SETTING_NUMBER_OF_REPLICAS, 1)
.put(SETTING_NUMBER_OF_REPLICAS, 0)
.build();
Node node1 = nodeBuilder().settings(settingsBuilder().put(settings).put("name", "node1")).node();
@ -61,11 +61,13 @@ public class TermsFacetSearchBenchmark {
Client client = clientNode.client();
long COUNT = SizeValue.parseSizeValue("1m").singles();
long COUNT = SizeValue.parseSizeValue("5m").singles();
int BATCH = 100;
int QUERY_WARMUP = 20;
int QUERY_COUNT = 200;
int NUMBER_OF_TERMS = 10;
int NUMBER_OF_TERMS = 200;
int NUMBER_OF_MULTI_VALUE_TERMS = 5;
int STRING_TERM_SIZE = 5;
long[] lValues = new long[NUMBER_OF_TERMS];
for (int i = 0; i < NUMBER_OF_TERMS; i++) {
@ -73,7 +75,7 @@ public class TermsFacetSearchBenchmark {
}
String[] sValues = new String[NUMBER_OF_TERMS];
for (int i = 0; i < NUMBER_OF_TERMS; i++) {
sValues[i] = Integer.toString(i);
sValues[i] = RandomStringGenerator.randomAlphabetic(STRING_TERM_SIZE);
}
Thread.sleep(10000);
@ -90,8 +92,22 @@ public class TermsFacetSearchBenchmark {
BulkRequestBuilder request = client.prepareBulk();
for (int j = 0; j < BATCH; j++) {
counter++;
XContentBuilder builder = jsonBuilder().startObject();
builder.field("id", Integer.toString(counter));
builder.field("s_value", sValues[counter % sValues.length]);
builder.field("i_value", lValues[counter % lValues.length]);
builder.startArray("sm_value");
for (int k = 0; k < NUMBER_OF_MULTI_VALUE_TERMS; k++) {
builder.value(sValues[ThreadLocalRandom.current().nextInt(sValues.length)]);
}
builder.endArray();
builder.endObject();
request.add(Requests.indexRequest("test").type("type1").id(Integer.toString(counter))
.source(source(Integer.toString(counter), sValues[counter % sValues.length], lValues[counter % lValues.length])));
.source(builder));
}
BulkResponse response = request.execute().actionGet();
if (response.hasFailures()) {
@ -113,23 +129,28 @@ public class TermsFacetSearchBenchmark {
client.admin().indices().prepareRefresh().execute().actionGet();
System.out.println("--> Number of docs in index: " + client.prepareCount().setQuery(matchAllQuery()).execute().actionGet().count());
System.out.println("--> Warmup...");
long totalQueryTime = 0;
// S_VALUE
System.out.println("--> Warmup (s_value) ...");
// run just the child query, warm up first
for (int j = 0; j < QUERY_WARMUP; j++) {
SearchResponse searchResponse = client.prepareSearch()
.setQuery(matchAllQuery())
.addFacet(termsFacet("s_value").field("s_value"))
.addFacet(termsFacet("l_value").field("l_value"))
.execute().actionGet();
if (j == 0) {
System.out.println("--> Warmup took: " + searchResponse.took());
System.out.println("--> Loading (s_value) took: " + searchResponse.took());
}
if (searchResponse.hits().totalHits() != COUNT) {
System.err.println("--> mismatch on hits");
}
}
System.out.println("--> Warmup (s_value) DONE");
long totalQueryTime = 0;
totalQueryTime = 0;
for (int j = 0; j < QUERY_COUNT; j++) {
SearchResponse searchResponse = client.prepareSearch()
.setQuery(matchAllQuery())
@ -142,6 +163,24 @@ public class TermsFacetSearchBenchmark {
}
System.out.println("--> Terms Facet (s_value) " + (totalQueryTime / QUERY_COUNT) + "ms");
client.admin().indices().prepareClearCache().setFieldDataCache(true).execute().actionGet();
System.out.println("--> Warmup (l_value) ...");
// run just the child query, warm up first
for (int j = 0; j < QUERY_WARMUP; j++) {
SearchResponse searchResponse = client.prepareSearch()
.setQuery(matchAllQuery())
.addFacet(termsFacet("l_value").field("l_value"))
.execute().actionGet();
if (j == 0) {
System.out.println("--> Loading (l_value) took: " + searchResponse.took());
}
if (searchResponse.hits().totalHits() != COUNT) {
System.err.println("--> mismatch on hits");
}
}
System.out.println("--> Warmup (l_value) DONE");
totalQueryTime = 0;
for (int j = 0; j < QUERY_COUNT; j++) {
SearchResponse searchResponse = client.prepareSearch()
@ -155,14 +194,41 @@ public class TermsFacetSearchBenchmark {
}
System.out.println("--> Terms Facet (l_value) " + (totalQueryTime / QUERY_COUNT) + "ms");
client.admin().indices().prepareClearCache().setFieldDataCache(true).execute().actionGet();
System.out.println("--> Warmup (sm_value) ...");
// run just the child query, warm up first
for (int j = 0; j < QUERY_WARMUP; j++) {
SearchResponse searchResponse = client.prepareSearch()
.setQuery(matchAllQuery())
.addFacet(termsFacet("sm_value").field("sm_value"))
.execute().actionGet();
if (j == 0) {
System.out.println("--> Loading (sm_value) took: " + searchResponse.took());
}
if (searchResponse.hits().totalHits() != COUNT) {
System.err.println("--> mismatch on hits");
}
}
System.out.println("--> Warmup (sm_value) DONE");
totalQueryTime = 0;
for (int j = 0; j < QUERY_COUNT; j++) {
SearchResponse searchResponse = client.prepareSearch()
.setQuery(matchAllQuery())
.addFacet(termsFacet("sm_value").field("sm_value"))
.execute().actionGet();
if (searchResponse.hits().totalHits() != COUNT) {
System.err.println("--> mismatch on hits");
}
totalQueryTime += searchResponse.tookInMillis();
}
System.out.println("--> Terms Facet (sm_value) " + (totalQueryTime / QUERY_COUNT) + "ms");
clientNode.close();
node1.close();
node2.close();
}
private static XContentBuilder source(String id, String sValue, long lValue) throws IOException {
return jsonBuilder().startObject().field("id", id).field("s_value", sValue).field("l_value", lValue).endObject();
}
}

View File

@ -0,0 +1,123 @@
/*
* Licensed to Elastic Search and Shay Banon under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. Elastic Search licenses this
* file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.benchmark.trove;
import org.elasticsearch.common.RandomStringGenerator;
import org.elasticsearch.common.StopWatch;
import org.elasticsearch.common.trove.map.hash.THashMap;
import org.elasticsearch.common.trove.map.hash.TObjectIntHashMap;
import org.elasticsearch.common.unit.SizeValue;
import java.util.HashMap;
public class StringMapAdjustOrPutBenchmark {
public static void main(String[] args) {
int NUMBER_OF_KEYS = (int) SizeValue.parseSizeValue("200k").singles();
int STRING_SIZE = 5;
long PUT_OPERATIONS = SizeValue.parseSizeValue("5m").singles();
long ITERATIONS = 10;
boolean REUSE = true;
String[] values = new String[NUMBER_OF_KEYS];
for (int i = 0; i < values.length; i++) {
values[i] = RandomStringGenerator.randomAlphabetic(STRING_SIZE);
}
StopWatch stopWatch;
stopWatch = new StopWatch().start();
TObjectIntHashMap<String> map = new TObjectIntHashMap<String>();
for (long iter = 0; iter < ITERATIONS; iter++) {
if (REUSE) {
map.clear();
} else {
map = new TObjectIntHashMap<String>();
}
for (long i = 0; i < PUT_OPERATIONS; i++) {
map.adjustOrPutValue(values[(int) (i % NUMBER_OF_KEYS)], 1, 1);
}
}
map.clear();
map = null;
System.out.println("TObjectIntHashMap: TP (seconds) " + ITERATIONS / stopWatch.stop().totalTime().secondsFrac());
// now test with THashMap
stopWatch = new StopWatch().start();
THashMap<String, StringEntry> tMap = new THashMap<String, StringEntry>();
for (long iter = 0; iter < ITERATIONS; iter++) {
if (REUSE) {
tMap.clear();
} else {
tMap = new THashMap<String, StringEntry>();
}
for (long i = 0; i < PUT_OPERATIONS; i++) {
String key = values[(int) (i % NUMBER_OF_KEYS)];
StringEntry stringEntry = tMap.get(key);
if (stringEntry == null) {
stringEntry = new StringEntry(key, 1);
tMap.put(key, stringEntry);
} else {
stringEntry.counter++;
}
}
}
System.out.println("THashMap: TP (seconds) " + ITERATIONS / stopWatch.stop().totalTime().secondsFrac());
tMap.clear();
tMap = null;
stopWatch = new StopWatch().start();
HashMap<String, StringEntry> hMap = new HashMap<String, StringEntry>();
for (long iter = 0; iter < ITERATIONS; iter++) {
if (REUSE) {
hMap.clear();
} else {
hMap = new HashMap<String, StringEntry>();
}
for (long i = 0; i < PUT_OPERATIONS; i++) {
String key = values[(int) (i % NUMBER_OF_KEYS)];
StringEntry stringEntry = hMap.get(key);
if (stringEntry == null) {
stringEntry = new StringEntry(key, 1);
hMap.put(key, stringEntry);
} else {
stringEntry.counter++;
}
}
}
System.out.println("HashMap: TP (seconds) " + ITERATIONS / stopWatch.stop().totalTime().secondsFrac());
}
static class StringEntry {
String key;
int counter;
StringEntry(String key, int counter) {
this.key = key;
this.counter = counter;
}
}
}

View File

@ -0,0 +1,305 @@
/*
* Licensed to Elastic Search and Shay Banon under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. Elastic Search licenses this
* file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.common;
import org.elasticsearch.common.util.concurrent.jsr166y.ThreadLocalRandom;
import java.util.Random;
public class RandomStringGenerator {
/**
* <p><code>RandomStringUtils</code> instances should NOT be constructed in
* standard programming. Instead, the class should be used as
* <code>RandomStringUtils.random(5);</code>.</p>
*
* <p>This constructor is public to permit tools that require a JavaBean instance
* to operate.</p>
*/
public RandomStringGenerator() {
super();
}
// Random
//-----------------------------------------------------------------------
/**
* <p>Creates a random string whose length is the number of characters
* specified.</p>
*
* <p>Characters will be chosen from the set of all characters.</p>
*
* @param count the length of random string to create
* @return the random string
*/
public static String random(int count) {
return random(count, false, false);
}
/**
* <p>Creates a random string whose length is the number of characters
* specified.</p>
*
* <p>Characters will be chosen from the set of characters whose
* ASCII value is between <code>32</code> and <code>126</code> (inclusive).</p>
*
* @param count the length of random string to create
* @return the random string
*/
public static String randomAscii(int count) {
return random(count, 32, 127, false, false);
}
/**
* <p>Creates a random string whose length is the number of characters
* specified.</p>
*
* <p>Characters will be chosen from the set of alphabetic
* characters.</p>
*
* @param count the length of random string to create
* @return the random string
*/
public static String randomAlphabetic(int count) {
return random(count, true, false);
}
/**
* <p>Creates a random string whose length is the number of characters
* specified.</p>
*
* <p>Characters will be chosen from the set of alpha-numeric
* characters.</p>
*
* @param count the length of random string to create
* @return the random string
*/
public static String randomAlphanumeric(int count) {
return random(count, true, true);
}
/**
* <p>Creates a random string whose length is the number of characters
* specified.</p>
*
* <p>Characters will be chosen from the set of numeric
* characters.</p>
*
* @param count the length of random string to create
* @return the random string
*/
public static String randomNumeric(int count) {
return random(count, false, true);
}
/**
* <p>Creates a random string whose length is the number of characters
* specified.</p>
*
* <p>Characters will be chosen from the set of alpha-numeric
* characters as indicated by the arguments.</p>
*
* @param count the length of random string to create
* @param letters if <code>true</code>, generated string will include
* alphabetic characters
* @param numbers if <code>true</code>, generated string will include
* numeric characters
* @return the random string
*/
public static String random(int count, boolean letters, boolean numbers) {
return random(count, 0, 0, letters, numbers);
}
/**
* <p>Creates a random string whose length is the number of characters
* specified.</p>
*
* <p>Characters will be chosen from the set of alpha-numeric
* characters as indicated by the arguments.</p>
*
* @param count the length of random string to create
* @param start the position in set of chars to start at
* @param end the position in set of chars to end before
* @param letters if <code>true</code>, generated string will include
* alphabetic characters
* @param numbers if <code>true</code>, generated string will include
* numeric characters
* @return the random string
*/
public static String random(int count, int start, int end, boolean letters, boolean numbers) {
return random(count, start, end, letters, numbers, null, ThreadLocalRandom.current());
}
/**
* <p>Creates a random string based on a variety of options, using
* default source of randomness.</p>
*
* <p>This method has exactly the same semantics as
* {@link #random(int, int, int, boolean, boolean, char[], Random)}, but
* instead of using an externally supplied source of randomness, it uses
* the internal static {@link Random} instance.</p>
*
* @param count the length of random string to create
* @param start the position in set of chars to start at
* @param end the position in set of chars to end before
* @param letters only allow letters?
* @param numbers only allow numbers?
* @param chars the set of chars to choose randoms from.
* If <code>null</code>, then it will use the set of all chars.
* @return the random string
* @throws ArrayIndexOutOfBoundsException if there are not
* <code>(end - start) + 1</code> characters in the set array.
*/
public static String random(int count, int start, int end, boolean letters, boolean numbers, char[] chars) {
return random(count, start, end, letters, numbers, chars, ThreadLocalRandom.current());
}
/**
* <p>Creates a random string based on a variety of options, using
* supplied source of randomness.</p>
*
* <p>If start and end are both <code>0</code>, start and end are set
* to <code>' '</code> and <code>'z'</code>, the ASCII printable
* characters, will be used, unless letters and numbers are both
* <code>false</code>, in which case, start and end are set to
* <code>0</code> and <code>Integer.MAX_VALUE</code>.
*
* <p>If set is not <code>null</code>, characters between start and
* end are chosen.</p>
*
* <p>This method accepts a user-supplied {@link Random}
* instance to use as a source of randomness. By seeding a single
* {@link Random} instance with a fixed seed and using it for each call,
* the same random sequence of strings can be generated repeatedly
* and predictably.</p>
*
* @param count the length of random string to create
* @param start the position in set of chars to start at
* @param end the position in set of chars to end before
* @param letters only allow letters?
* @param numbers only allow numbers?
* @param chars the set of chars to choose randoms from.
* If <code>null</code>, then it will use the set of all chars.
* @param random a source of randomness.
* @return the random string
* @throws ArrayIndexOutOfBoundsException if there are not
* <code>(end - start) + 1</code> characters in the set array.
* @throws IllegalArgumentException if <code>count</code> &lt; 0.
* @since 2.0
*/
public static String random(int count, int start, int end, boolean letters, boolean numbers,
char[] chars, Random random) {
if (count == 0) {
return "";
} else if (count < 0) {
throw new IllegalArgumentException("Requested random string length " + count + " is less than 0.");
}
if ((start == 0) && (end == 0)) {
end = 'z' + 1;
start = ' ';
if (!letters && !numbers) {
start = 0;
end = Integer.MAX_VALUE;
}
}
char[] buffer = new char[count];
int gap = end - start;
while (count-- != 0) {
char ch;
if (chars == null) {
ch = (char) (random.nextInt(gap) + start);
} else {
ch = chars[random.nextInt(gap) + start];
}
if ((letters && Character.isLetter(ch))
|| (numbers && Character.isDigit(ch))
|| (!letters && !numbers)) {
if (ch >= 56320 && ch <= 57343) {
if (count == 0) {
count++;
} else {
// low surrogate, insert high surrogate after putting it in
buffer[count] = ch;
count--;
buffer[count] = (char) (55296 + random.nextInt(128));
}
} else if (ch >= 55296 && ch <= 56191) {
if (count == 0) {
count++;
} else {
// high surrogate, insert low surrogate before putting it in
buffer[count] = (char) (56320 + random.nextInt(128));
count--;
buffer[count] = ch;
}
} else if (ch >= 56192 && ch <= 56319) {
// private high surrogate, no effing clue, so skip it
count++;
} else {
buffer[count] = ch;
}
} else {
count++;
}
}
return new String(buffer);
}
/**
* <p>Creates a random string whose length is the number of characters
* specified.</p>
*
* <p>Characters will be chosen from the set of characters
* specified.</p>
*
* @param count the length of random string to create
* @param chars the String containing the set of characters to use,
* may be null
* @return the random string
* @throws IllegalArgumentException if <code>count</code> &lt; 0.
*/
public static String random(int count, String chars) {
if (chars == null) {
return random(count, 0, 0, false, false, null, ThreadLocalRandom.current());
}
return random(count, chars.toCharArray());
}
/**
* <p>Creates a random string whose length is the number of characters
* specified.</p>
*
* <p>Characters will be chosen from the set of characters specified.</p>
*
* @param count the length of random string to create
* @param chars the character array containing the set of characters to use,
* may be null
* @return the random string
* @throws IllegalArgumentException if <code>count</code> &lt; 0.
*/
public static String random(int count, char[] chars) {
if (chars == null) {
return random(count, 0, 0, false, false, null, ThreadLocalRandom.current());
}
return random(count, 0, chars.length, false, false, chars, ThreadLocalRandom.current());
}
}