LongFieldDataBenchmark.java 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. /*
  2. * Licensed to Elasticsearch under one or more contributor
  3. * license agreements. See the NOTICE file distributed with
  4. * this work for additional information regarding copyright
  5. * ownership. Elasticsearch licenses this file to you under
  6. * the Apache License, Version 2.0 (the "License"); you may
  7. * not use this file except in compliance with the License.
  8. * You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing,
  13. * software distributed under the License is distributed on an
  14. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  15. * KIND, either express or implied. See the License for the
  16. * specific language governing permissions and limitations
  17. * under the License.
  18. */
  19. package org.elasticsearch.benchmark.fielddata;
  20. import org.apache.lucene.analysis.core.KeywordAnalyzer;
  21. import org.apache.lucene.document.Document;
  22. import org.apache.lucene.document.Field.Store;
  23. import org.apache.lucene.document.LongField;
  24. import org.apache.lucene.index.DirectoryReader;
  25. import org.apache.lucene.index.IndexWriter;
  26. import org.apache.lucene.index.IndexWriterConfig;
  27. import org.apache.lucene.index.SlowCompositeReaderWrapper;
  28. import org.apache.lucene.store.RAMDirectory;
  29. import org.apache.lucene.util.RamUsageEstimator;
  30. import org.elasticsearch.common.lucene.Lucene;
  31. import org.elasticsearch.index.Index;
  32. import org.elasticsearch.index.fielddata.AtomicNumericFieldData;
  33. import org.elasticsearch.index.fielddata.IndexFieldDataService;
  34. import org.elasticsearch.index.fielddata.IndexNumericFieldData;
  35. import org.elasticsearch.index.mapper.ContentPath;
  36. import org.elasticsearch.index.mapper.Mapper.BuilderContext;
  37. import org.elasticsearch.index.mapper.core.LongFieldMapper;
  38. import org.elasticsearch.indices.breaker.NoneCircuitBreakerService;
  39. import java.util.Random;
  40. public class LongFieldDataBenchmark {
  41. private static final Random RANDOM = new Random();
  42. private static final int SECONDS_PER_YEAR = 60 * 60 * 24 * 365;
  43. public static enum Data {
  44. SINGLE_VALUES_DENSE_ENUM {
  45. public int numValues() {
  46. return 1;
  47. }
  48. @Override
  49. public long nextValue() {
  50. return RANDOM.nextInt(16);
  51. }
  52. },
  53. SINGLE_VALUED_DENSE_DATE {
  54. public int numValues() {
  55. return 1;
  56. }
  57. @Override
  58. public long nextValue() {
  59. // somewhere in-between 2010 and 2012
  60. return 1000L * (40L * SECONDS_PER_YEAR + RANDOM.nextInt(2 * SECONDS_PER_YEAR));
  61. }
  62. },
  63. MULTI_VALUED_DATE {
  64. public int numValues() {
  65. return RANDOM.nextInt(3);
  66. }
  67. @Override
  68. public long nextValue() {
  69. // somewhere in-between 2010 and 2012
  70. return 1000L * (40L * SECONDS_PER_YEAR + RANDOM.nextInt(2 * SECONDS_PER_YEAR));
  71. }
  72. },
  73. MULTI_VALUED_ENUM {
  74. public int numValues() {
  75. return RANDOM.nextInt(3);
  76. }
  77. @Override
  78. public long nextValue() {
  79. return 3 + RANDOM.nextInt(8);
  80. }
  81. },
  82. SINGLE_VALUED_SPARSE_RANDOM {
  83. public int numValues() {
  84. return RANDOM.nextFloat() < 0.1f ? 1 : 0;
  85. }
  86. @Override
  87. public long nextValue() {
  88. return RANDOM.nextLong();
  89. }
  90. },
  91. MULTI_VALUED_SPARSE_RANDOM {
  92. public int numValues() {
  93. return RANDOM.nextFloat() < 0.1f ? 1 + RANDOM.nextInt(5) : 0;
  94. }
  95. @Override
  96. public long nextValue() {
  97. return RANDOM.nextLong();
  98. }
  99. },
  100. MULTI_VALUED_DENSE_RANDOM {
  101. public int numValues() {
  102. return 1 + RANDOM.nextInt(3);
  103. }
  104. @Override
  105. public long nextValue() {
  106. return RANDOM.nextLong();
  107. }
  108. };
  109. public abstract int numValues();
  110. public abstract long nextValue();
  111. }
  112. public static void main(String[] args) throws Exception {
  113. final IndexWriterConfig iwc = new IndexWriterConfig(Lucene.VERSION, new KeywordAnalyzer());
  114. final String fieldName = "f";
  115. final int numDocs = 1000000;
  116. System.out.println("Data\tLoading time\tImplementation\tActual size\tExpected size");
  117. for (Data data : Data.values()) {
  118. final RAMDirectory dir = new RAMDirectory();
  119. final IndexWriter indexWriter = new IndexWriter(dir, iwc);
  120. for (int i = 0; i < numDocs; ++i) {
  121. final Document doc = new Document();
  122. final int numFields = data.numValues();
  123. for (int j = 0; j < numFields; ++j) {
  124. doc.add(new LongField(fieldName, data.nextValue(), Store.NO));
  125. }
  126. indexWriter.addDocument(doc);
  127. }
  128. indexWriter.forceMerge(1, true);
  129. indexWriter.close();
  130. final DirectoryReader dr = DirectoryReader.open(dir);
  131. final IndexFieldDataService fds = new IndexFieldDataService(new Index("dummy"), new NoneCircuitBreakerService());
  132. final LongFieldMapper mapper = new LongFieldMapper.Builder(fieldName).build(new BuilderContext(null, new ContentPath(1)));
  133. final IndexNumericFieldData fd = fds.getForField(mapper);
  134. final long start = System.nanoTime();
  135. final AtomicNumericFieldData afd = fd.loadDirect(SlowCompositeReaderWrapper.wrap(dr).getContext());
  136. final long loadingTimeMs = (System.nanoTime() - start) / 1000 / 1000;
  137. System.out.println(data + "\t" + loadingTimeMs + "\t" + afd.getClass().getSimpleName() + "\t" + RamUsageEstimator.humanReadableUnits(afd.ramBytesUsed()));
  138. dr.close();
  139. }
  140. }
  141. }