org.openstreetmap.josm.data.osm.KeyValuePerformanceTest.java Source code

Java tutorial

Introduction

Here is the source code for org.openstreetmap.josm.data.osm.KeyValuePerformanceTest.java

Source

// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.data.osm;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;

import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Random;

import org.apache.commons.lang.RandomStringUtils;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.Timeout;
import org.openstreetmap.josm.JOSMFixture;
import org.openstreetmap.josm.PerformanceTestUtils;
import org.openstreetmap.josm.PerformanceTestUtils.PerformanceTestTimer;
import org.openstreetmap.josm.data.osm.OsmDataGenerator.KeyValueDataGenerator;

import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;

/**
 * This test measures the performance of {@link OsmPrimitive#get(String)} and related.
 * @author Michael Zangl
 */
public class KeyValuePerformanceTest {
    private static final int PUT_RUNS = 10000;
    private static final int GET_RUNS = 100000;
    private static final int TEST_STRING_COUNT = 10000;
    private static final int STRING_INTERN_TESTS = 5000000;
    private static final double[] TAG_NODE_RATIOS = new double[] { .05, .3, 3, 20, 200 };
    private ArrayList<String> testStrings = new ArrayList<>();
    private Random random;

    /**
     * Global timeout applied to all test methods.
     */
    @Rule
    @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
    public Timeout globalTimeout = Timeout.seconds(15 * 60);

    /**
     * Prepare the test.
     */
    @BeforeClass
    public static void createJOSMFixture() {
        JOSMFixture.createPerformanceTestFixture().init(true);
    }

    /**
     * See if there is a big difference between Strings that are interned and those that are not.
     */
    @Test
    @SuppressFBWarnings(value = "DM_STRING_CTOR", justification = "test Strings that are interned and those that are not")
    public void testMeasureStringEqualsIntern() {
        String str1Interned = "string1";
        String str1InternedB = "string1";
        String str1 = new String(str1Interned);
        String str1B = new String(str1Interned);
        String str2Interned = "string2";
        String str2 = new String(str2Interned);

        for (int i = 0; i < STRING_INTERN_TESTS; i++) {
            // warm up
            assertEquals(str1, str1B);
        }

        PerformanceTestTimer timer = PerformanceTestUtils.startTimer("Assertion overhead.");
        for (int i = 0; i < STRING_INTERN_TESTS; i++) {
            assertTrue(true);
        }
        timer.done();

        timer = PerformanceTestUtils.startTimer("str1.equals(str2) succeeds (without intern)");
        for (int i = 0; i < STRING_INTERN_TESTS; i++) {
            assertEquals(str1, str1B);
        }
        timer.done();

        timer = PerformanceTestUtils.startTimer("str1 == str2 succeeds");
        for (int i = 0; i < STRING_INTERN_TESTS; i++) {
            assertSame(str1Interned, str1InternedB);
        }
        timer.done();

        timer = PerformanceTestUtils.startTimer("str1 == str2.intern() succeeds");
        for (int i = 0; i < STRING_INTERN_TESTS; i++) {
            assertSame(str1Interned, str1.intern());
        }
        timer.done();

        timer = PerformanceTestUtils.startTimer("str1 == str2.intern() succeeds for interned string");
        for (int i = 0; i < STRING_INTERN_TESTS; i++) {
            assertSame(str1Interned, str1InternedB.intern());
        }
        timer.done();

        timer = PerformanceTestUtils.startTimer("str1.equals(str2) = fails (without intern)");
        for (int i = 0; i < STRING_INTERN_TESTS; i++) {
            assertFalse(str1.equals(str2));
        }
        timer.done();

        timer = PerformanceTestUtils.startTimer("str1 == str2 fails");
        for (int i = 0; i < STRING_INTERN_TESTS; i++) {
            assertNotSame(str1Interned, str2Interned);
        }
        timer.done();

        timer = PerformanceTestUtils.startTimer("str1 == str2.intern() fails");
        for (int i = 0; i < STRING_INTERN_TESTS; i++) {
            assertNotSame(str1Interned, str2.intern());
        }
        timer.done();
    }

    /**
     * Generate an array of test strings.
     */
    @Before
    public void generateTestStrings() {
        testStrings.clear();
        random = new SecureRandom();
        for (int i = 0; i < TEST_STRING_COUNT; i++) {
            testStrings.add(RandomStringUtils.random(10, 0, 0, true, true, null, random));
        }
    }

    /**
     * Measure the speed of {@link OsmPrimitive#put(String, String)}
     */
    @Test
    public void testKeyValuePut() {
        for (double tagNodeRatio : TAG_NODE_RATIOS) {
            int nodeCount = (int) (PUT_RUNS / tagNodeRatio);
            KeyValueDataGenerator generator = OsmDataGenerator.getKeyValue(nodeCount, 0);
            generator.generateDataSet();

            PerformanceTestTimer timer = PerformanceTestUtils
                    .startTimer("OsmPrimitive#put(String, String) with put/node ratio " + tagNodeRatio);

            for (int i = 0; i < PUT_RUNS; i++) {
                String key = generator.randomKey();
                String value = generator.randomValue();
                generator.randomNode().put(key, value);
            }

            timer.done();
        }
    }

    /**
     * Measure the speed of {@link OsmPrimitive#get(String)}
     */
    @Test
    public void testKeyValueGet() {
        for (double tagNodeRatio : TAG_NODE_RATIOS) {
            KeyValueDataGenerator generator = OsmDataGenerator.getKeyValue(tagNodeRatio);
            generator.generateDataSet();

            PerformanceTestTimer timer = PerformanceTestUtils
                    .startTimer("OsmPrimitive#get(String) with tag/node ratio " + tagNodeRatio);
            for (int i = 0; i < GET_RUNS; i++) {
                String key = generator.randomKey();
                // to make comparison easier.
                generator.randomValue();
                generator.randomNode().get(key);
            }
            timer.done();
        }
    }

    /**
     * Measure the speed of {@link OsmPrimitive#getKeys()}
     */
    @Test
    public void testKeyValueGetKeys() {
        for (double tagNodeRatio : TAG_NODE_RATIOS) {
            KeyValueDataGenerator generator = OsmDataGenerator.getKeyValue(tagNodeRatio);
            generator.generateDataSet();

            PerformanceTestTimer timer = PerformanceTestUtils
                    .startTimer("OsmPrimitive#getKeys() with tag/node ratio " + tagNodeRatio);

            for (int i = 0; i < GET_RUNS; i++) {
                // to make comparison easier.
                generator.randomKey();
                generator.randomValue();
                generator.randomNode().getKeys();
            }
            timer.done();
        }
    }

    /**
     * Measure the speed of {@link OsmPrimitive#getKeys()}.get(key)
     */
    @Test
    @SuppressFBWarnings(value = "RV_RETURN_VALUE_IGNORED_NO_SIDE_EFFECT")
    public void testKeyValueGetKeysGet() {
        for (double tagNodeRatio : TAG_NODE_RATIOS) {
            KeyValueDataGenerator generator = OsmDataGenerator.getKeyValue(tagNodeRatio);
            generator.generateDataSet();

            PerformanceTestTimer timer = PerformanceTestUtils
                    .startTimer("OsmPrimitive#getKeys().get(key) with tag/node ratio " + tagNodeRatio);
            for (int i = 0; i < GET_RUNS; i++) {
                String key = generator.randomKey();
                // to make comparison easier.
                generator.randomValue();
                generator.randomNode().getKeys().get(key);
            }
            timer.done();
        }
    }
}