/* * Hibernate OGM, Domain model persistence for NoSQL datastores * * License: GNU Lesser General Public License (LGPL), version 2.1 or later * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>. */ package org.hibernate.ogm.perftest.mongodb.nativeapi; import java.util.ArrayList; import java.util.Date; import java.util.List; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.OperationsPerInvocation; import org.openjdk.jmh.annotations.Scope; import org.openjdk.jmh.annotations.Setup; import org.openjdk.jmh.annotations.State; import org.openjdk.jmh.infra.Blackhole; import com.mongodb.BasicDBObject; import com.mongodb.DBCollection; import com.mongodb.DBCursor; import com.mongodb.DBObject; /** * Benchmark for measuring performance of find-by-id / query operations using the native MongoDB API. * * @author Gunnar Morling */ public class NativeApiFindBenchmark extends NativeApiBenchmarkBase { public static final int NUMBER_OF_TEST_ENTITIES = 10000; /** * The number of operations to be performed with one entity manager. Using an EM only for one op is an anti-pattern, * but setting the number too high will result in an unrealistic result. Aim for a value to be expected during the * processing of one web request or similar. */ private static final int OPERATIONS_PER_INVOCATION = 100; @State(Scope.Benchmark) public static class TestDataInserter { ClientHolder clientHolder; @Setup public void setupDatastore(ClientHolder clientHolder) throws Exception { this.clientHolder = clientHolder; DBCollection authorCollection = clientHolder.db.getCollection( "Author" ); List<DBObject> authors = new ArrayList<DBObject>( 1000 ); for ( long i = 0; i <= NUMBER_OF_TEST_ENTITIES; i++ ) { DBObject author = new BasicDBObject( 5 ); author.put( "_id", i ); author.put( "bio", "This is a decent size bio made of " + clientHolder.rand.nextDouble() + " stuffs" ); author.put( "dob", new Date() ); author.put( "fname", "Jessie " + clientHolder.rand.nextInt() ); author.put( "lname", "Landis " + clientHolder.rand.nextInt() ); author.put( "mname", "" + clientHolder.rand.nextInt( 26 ) ); authors.add( author ); if ( i % 1000 == 0 ) { authorCollection.insert( authors ); System.out.println( "Inserted " + i + " entities" ); authors = new ArrayList<DBObject>( 1000 ); } } authorCollection.createIndex( new BasicDBObject( "mname", 1 ) ); } } @Benchmark @OperationsPerInvocation(OPERATIONS_PER_INVOCATION) public void findEntityById(TestDataInserter inserter, Blackhole blackhole) throws Exception { ClientHolder clientHolder = inserter.clientHolder; DBCollection authorCollection = clientHolder.db.getCollection( "Author" ); for ( int i = 0; i < OPERATIONS_PER_INVOCATION; i++ ) { long id = clientHolder.rand.nextInt( NUMBER_OF_TEST_ENTITIES - 1 ) + 1; DBObject author = authorCollection.findOne( new BasicDBObject( "_id", id ) ); if ( author == null ) { throw new IllegalArgumentException( "Couldn't find entry with id " + id ); } blackhole.consume( author.get( "lname" ) ); } } @Benchmark @OperationsPerInvocation(OPERATIONS_PER_INVOCATION) public void findEntityByProperty(TestDataInserter inserter, Blackhole blackhole) throws Exception { ClientHolder clientHolder = inserter.clientHolder; DBCollection authorCollection = clientHolder.db.getCollection( "Author" ); for ( int i = 0; i < OPERATIONS_PER_INVOCATION; i++ ) { int mName = clientHolder.rand.nextInt( 26 ); DBCursor authors = authorCollection.find( new BasicDBObject( "mname", "" + mName ) ).limit( 50 ); DBObject author; while ( authors.hasNext() ) { author = authors.next(); blackhole.consume( author.get( "lname" ) ); } } } }