See: Description
Class | Description |
---|---|
Benchmark |
Run the benchmark algorithm.
|
PerfRunData |
Data maintained by a performance test run.
|
This package provides "task based" performance benchmarking of Lucene. One can use the predefined benchmarks, or create new ones.
Contained packages:
Package | Description |
stats | Statistics maintained when running benchmark tasks. |
tasks | Benchmark tasks. |
feeds | Sources for benchmark inputs: documents and queries. |
utils | Utilities used for the benchmark, and for the reports. |
programmatic | Sample performance test written programatically. |
Benchmark Lucene using task primitives.
A benchmark is composed of some predefined tasks, allowing for creating an index, adding documents, optimizing, searching, generating reports, and more. A benchmark run takes an "algorithm" file that contains a description of the sequence of tasks making up the run, and some properties defining a few additional characteristics of the benchmark run.
Easiest way to run a benchmarks is using the predefined ant task:
micro-standard.alg
"algorithm".
compound-penalty.alg
"algorithm".
your perf test
"algorithm".
You may find existing tasks sufficient for defining the benchmark you need, otherwise, you can extend the framework to meet your needs, as explained herein.
Each benchmark run has a DocMaker and a QueryMaker. These two should usually match, so that "meaningful" queries are used for a certain collection. Properties set at the header of the alg file define which "makers" should be used. You can also specify your own makers, extending DocMaker and implementing QureyMaker.
Note: since 2.9, DocMaker is a concrete class which accepts a ContentSource. In most cases, you can use the DocMaker class to create Documents, while providing your own ContentSource implementation. For example, the current Benchmark package includes ContentSource implementations for TREC, Enwiki and Reuters collections, as well as others like LineDocSource which reads a 'line' file produced by WriteLineDocTask.
Benchmark .alg file contains the benchmark "algorithm". The syntax is described below. Within the algorithm, you can specify groups of commands, assign them names, specify commands that should be repeated, do commands in serial or in parallel, and also control the speed of "firing" the commands.
This allows, for instance, to specify that an index should be opened for update, documents should be added to it one by one but not faster than 20 docs a minute, and, in parallel with this, some N queries should be searched against that index, again, no more than 2 queries a second. You can have the searches all share an index reader, or have them each open its own reader and close it afterwords.
If the commands available for use in the algorithm do not meet your needs, you can add commands by adding a new task under org.apache.lucene.benchmark.byTask.tasks - you should extend the PerfTask abstract class. Make sure that your new task class name is suffixed by Task. Assume you added the class "WonderfulTask" - doing so also enables the command "Wonderful" to be used in the algorithm.
External classes: It is sometimes useful to invoke the benchmark package with your external alg file that configures the use of your own doc/query maker and or html parser. You can work this out without modifying the benchmark package code, by passing your class path with the benchmark.ext.classpath property:
The following is an informal description of the supported syntax.
doc.delete.step
property.
name,value mandatory param,
',' used as a separator.
Existing tasks can be divided into a few groups: regular index/search work tasks, report tasks, and control tasks.
Properties are read from the header of the .alg file, and define several parameters of the performance test. As mentioned above for the NewRound task, numeric and boolean properties that are defined as a sequence of values, e.g. merge.factor=mrg:10:100:10:100 would increment (cyclic) to the next value, when NewRound is called, and would also appear as a named column in the reports (column name would be "mrg" in this example).
Some of the currently defined properties are:
Here is a list of currently defined properties:
For sample use of these properties see the *.alg files under conf.
The following example is in conf/sample.alg:
# -------------------------------------------------------- # # Sample: what is the effect of doc size on indexing time? # # There are two parts in this test: # - PopulateShort adds 2N documents of length L # - PopulateLong adds N documents of length 2L # Which one would be faster? # The comparison is done twice. # # -------------------------------------------------------- # ------------------------------------------------------------------------------------- # multi val params are iterated by NewRound's, added to reports, start with column name. merge.factor=mrg:10:20 max.buffered=buf:100:1000 compound=true analyzer=org.apache.lucene.analysis.standard.StandardAnalyzer directory=FSDirectory doc.stored=true doc.tokenized=true doc.term.vector=false doc.add.log.step=500 docs.dir=reuters-out doc.maker=org.apache.lucene.benchmark.byTask.feeds.SimpleDocMaker query.maker=org.apache.lucene.benchmark.byTask.feeds.SimpleQueryMaker # task at this depth or less would print when they start task.max.depth.log=2 log.queries=false # ------------------------------------------------------------------------------------- { { "PopulateShort" CreateIndex { AddDoc(4000) > : 20000 Optimize CloseIndex > ResetSystemErase { "PopulateLong" CreateIndex { AddDoc(8000) > : 10000 Optimize CloseIndex > ResetSystemErase NewRound } : 2 RepSumByName RepSelectByPref Populate
The command line for running this sample:
ant run-task -Dtask.alg=conf/sample.alg
The output report from running this test contains the following:
Operation round mrg buf runCnt recsPerRun rec/s elapsedSec avgUsedMem avgTotalMem PopulateShort 0 10 100 1 20003 119.6 167.26 12,959,120 14,241,792 PopulateLong - - 0 10 100 - - 1 - - 10003 - - - 74.3 - - 134.57 - 17,085,208 - 20,635,648 PopulateShort 1 20 1000 1 20003 143.5 139.39 63,982,040 94,756,864 PopulateLong - - 1 20 1000 - - 1 - - 10003 - - - 77.0 - - 129.92 - 87,309,608 - 100,831,232
Two columns in the results table indicate records counts: records-per-run and records-per-second. What does it mean?
Almost every task gets 1 in this count just for being executed. Task sequences aggregate the counts of their child tasks, plus their own count of 1. So, a task sequence containing 5 other task sequences, each running a single other task 10 times, would have a count of 1 + 5 * (1 + 10) = 56.
The traverse and retrieve tasks "count" more: a traverse task would add 1 for each traversed result (hit), and a retrieve task would additionally add 1 for each retrieved doc. So, regular Search would count 1, SearchTrav that traverses 10 hits would count 11, and a SearchTravRet task that retrieves (and traverses) 10, would count 21.
Confusing? this might help: always examine the elapsedSec
column,
and always compare "apples to apples", .i.e. it is interesting to check how the
rec/s
changed for the same task (or sequence) between two
different runs, but it is not very useful to know how the rec/s
differs between Search
and SearchTrav
tasks. For
the latter, elapsedSec
would bring more insight.