Forum Stats

  • 3,768,743 Users
  • 2,252,843 Discussions
  • 7,874,705 Comments

Discussions

What's wrong?

coolnight
coolnight Member Posts: 5
edited Jul 27, 2006 12:04PM in Berkeley DB Java Edition
I want to write a small program to test how fast je is.
but the result is disappointing.
it's very slow.If I enable database transaction, it'll use 20s to write 1000records.
if I don't enable database transaction, it'll be much faster,but not stable.
maybe something is wrong,here is the code, it needs jdk5.0!
the first copy is for reading, the second copy is used to copy and paste into java ide to run it!
Thanks!
package tests;

import java.io.File;

import com.sleepycat.bind.EntryBinding;
import com.sleepycat.bind.tuple.TupleBinding;
import com.sleepycat.je.Database;
import com.sleepycat.je.DatabaseConfig;
import com.sleepycat.je.DatabaseEntry;
import com.sleepycat.je.DatabaseException;
import com.sleepycat.je.Environment;
import com.sleepycat.je.EnvironmentConfig;
import com.sleepycat.je.EnvironmentStats;
import com.sleepycat.je.StatsConfig;

public class BdbTest {

    private Environment myEnv;
    private Database    simpleDb;

    private int         num = 10000;

    /**
     * @param args
     */
    public static void main(String[] args) throws DatabaseException {
        int num = 10000;
        if (args.length > 0) num = Integer.parseInt(args[0]);
        BdbTest bm = new BdbTest();
        bm.num = num;
        bm.init();
        bm.write();
        bm.close();
    }

    public void write() throws DatabaseException {
        EntryBinding myBinding = TupleBinding.getPrimitiveBinding(Long.class);
        DatabaseEntry theKey = new DatabaseEntry();
        DatabaseEntry theData = new DatabaseEntry();

        final int cap = 1000;
        //long total_counts = 0;
        long start = System.nanoTime();
        long lastEnd = start;

        for (long i = 0; i < num; i++) {
            //
            Long l = Long.valueOf(i);
            //                      theKey = new DatabaseEntry();
            //                      theData = new DatabaseEntry();

            myBinding.objectToEntry(l, theKey);
            myBinding.objectToEntry(l, theData);

            simpleDb.put(null, theKey, theData);

            if (i % cap == 0) {
                long end1 = System.nanoTime();
                System.out.println(String.format("it takes [%d] us to put [%d] records!", (end1 - lastEnd) / 1000, cap));
                lastEnd = end1;
            }
        }
        long end = System.nanoTime();
        System.out.println(String.format("it takes [%d] us to write [%d] records!", (end - start) / 1000, num));
        StatsConfig config = new StatsConfig();
        config.setClear(true);
        config.setFast(true);
        config.setShowProgressInterval(1000);
        EnvironmentStats stats = myEnv.getStats(config);

        System.out.println("stats=" + stats);
    }

    public void init() throws DatabaseException {
        File envHome = new File(".");
        boolean readOnly = false;
        EnvironmentConfig myEnvConfig = new EnvironmentConfig();
        DatabaseConfig myDbConfig = new DatabaseConfig();

        // If the environment is read-only, then
        // make the databases read-only too.
        myEnvConfig.setReadOnly(readOnly);
        myDbConfig.setReadOnly(readOnly);

        // If the environment is opened for write, then we want to be 
        // able to create the environment and databases if 
        // they do not exist.
        myEnvConfig.setAllowCreate(!readOnly);
        myDbConfig.setAllowCreate(!readOnly);

        // Allow transactions if we are writing to the database
        myEnvConfig.setTransactional(true);
        myDbConfig.setTransactional(false);

        // Open the environment
        myEnv = new Environment(envHome, myEnvConfig);

        System.out.println("cachesize=" + myEnv.getConfig().getCacheSize());
        System.out.println("config=" + myEnv.getConfig());
        System.out.println("cache percent=" + myEnv.getConfig().getCachePercent());
        // Now open, or create and open, our databases
        // Open the vendors and inventory databases
        simpleDb = myEnv.openDatabase(null, "simpleDB", myDbConfig);
    }

    public void close() {
        if (myEnv != null) {
            try {
                //Close the secondary before closing the primaries
                simpleDb.close();
                // Finally, close the environment.
                myEnv.close();
            } catch (DatabaseException dbe) {
                System.err.println("Error closing MyDbEnv: " + dbe.toString());
                System.exit(-1);
            }
        }
    }

}
package tests;
import java.io.File;
import com.sleepycat.bind.EntryBinding;
import com.sleepycat.bind.tuple.TupleBinding;
import com.sleepycat.je.Database;
import com.sleepycat.je.DatabaseConfig;
import com.sleepycat.je.DatabaseEntry;
import com.sleepycat.je.DatabaseException;
import com.sleepycat.je.Environment;
import com.sleepycat.je.EnvironmentConfig;
import com.sleepycat.je.EnvironmentStats;
import com.sleepycat.je.StatsConfig;
public class BdbTest {
private Environment myEnv;
private Database simpleDb;
private int num = 10000;
/**
* @param args
*/
public static void main(String[] args) throws DatabaseException {
int num = 10000;
if (args.length > 0) num = Integer.parseInt(args[0]);
BdbTest bm = new BdbTest();
bm.num = num;
bm.init();
bm.write();
bm.close();
}
public void write() throws DatabaseException {
EntryBinding myBinding = TupleBinding.getPrimitiveBinding(Long.class);
DatabaseEntry theKey = new DatabaseEntry();
DatabaseEntry theData = new DatabaseEntry();
final int cap = 1000;
//long total_counts = 0;
long start = System.nanoTime();
long lastEnd = start;
for (long i = 0; i < num; i++) {
//
Long l = Long.valueOf(i);
// theKey = new DatabaseEntry();
// theData = new DatabaseEntry();
myBinding.objectToEntry(l, theKey);
myBinding.objectToEntry(l, theData);
simpleDb.put(null, theKey, theData);
if (i % cap == 0) {
long end1 = System.nanoTime();
System.out.println(String.format("it takes [%d] us to put [%d] records!", (end1 - lastEnd) / 1000, cap));
lastEnd = end1;
}
}
long end = System.nanoTime();
System.out.println(String.format("it takes [%d] us to write [%d] records!", (end - start) / 1000, num));
StatsConfig config = new StatsConfig();
config.setClear(true);
config.setFast(true);
config.setShowProgressInterval(1000);
EnvironmentStats stats = myEnv.getStats(config);
System.out.println("stats=" + stats);
}
public void init() throws DatabaseException {
File envHome = new File(".");
boolean readOnly = false;
EnvironmentConfig myEnvConfig = new EnvironmentConfig();
DatabaseConfig myDbConfig = new DatabaseConfig();
// If the environment is read-only, then
// make the databases read-only too.
myEnvConfig.setReadOnly(readOnly);
myDbConfig.setReadOnly(readOnly);
// If the environment is opened for write, then we want to be
// able to create the environment and databases if
// they do not exist.
myEnvConfig.setAllowCreate(!readOnly);
myDbConfig.setAllowCreate(!readOnly);
// Allow transactions if we are writing to the database
myEnvConfig.setTransactional(true);
myDbConfig.setTransactional(false);
// Open the environment
myEnv = new Environment(envHome, myEnvConfig);
System.out.println("cachesize=" + myEnv.getConfig().getCacheSize());
System.out.println("config=" + myEnv.getConfig());
System.out.println("cache percent=" + myEnv.getConfig().getCachePercent());
// Now open, or create and open, our databases
// Open the vendors and inventory databases
simpleDb = myEnv.openDatabase(null, "simpleDB", myDbConfig);
}
public void close() {
if (myEnv != null) {
try {
//Close the secondary before closing the primaries
simpleDb.close();
// Finally, close the environment.
myEnv.close();
} catch (DatabaseException dbe) {
System.err.println("Error closing MyDbEnv: " + dbe.toString());
System.exit(-1);
}
}
}
}

Comments

  • my computer is Celeron(R) 2.66G/1G ram
  • 512799
    512799 Member Posts: 494
    Hi,

    I have reviewed your test program and first have a question:
    What is it you want to accomplish? Are you trying to look at loading a large batch of records at once? If so why do you need transactions at all?

    Assuming you do want transactions you have some other parameters that can help this run faster depending on your requirements for durability. If you run with transactions and take the default settings (as I believe you have) you will end up flushing the log buffer for each put to achieve the highest level of durability. There are other sync options that you can consider. This is described in more detail in the following FAQ entry:

    http://dev.sleepycat.com/resources/faq_show.html?id=39

    I would recommend trying the test with the other 2 settings, (commitWriteNoSync and commitNoSync).

    If you are running with CommitSync , each put (with auto commit) will result in the log buffer being flushed all the way to disk. Your elapsed time will be very much dependent on the speed of the I/O to disk on your Celeron. If I/O to disk on your system is slow, then this will be noticed since you are flushing to disk for each record.

    Try the different settings and see what type of numbers you get.
    What is your cache size? Another reference you may find useful can be found here:

    http://www.sleepycat.com/jedocs/GettingStartedGuide/cachesize.html

    I hope this helps, let us know if you have further questions.

    Regards,

    Ron Cohen
    Berkeley DB Java Edition
    Oracle Corporation
  • 512799
    512799 Member Posts: 494
    Hi again,

    I have one more suggestion:

    Depending on your requirements you may want to consider a
    Deferred Write Database:

    http://www.sleepycat.com/jedocs/GettingStartedGuide/DB.html#dwdatabase

    Ron
This discussion has been closed.