Java tutorial
/* * Copyright 2015 Daniel Huss * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * specific language governing permissions and limitations under the License. */ package de.unentscheidbar.csv2; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Random; import java.util.Set; import java.util.concurrent.TimeUnit; import org.apache.commons.collections4.map.CaseInsensitiveMap; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; import org.openjdk.jmh.annotations.Fork; import org.openjdk.jmh.annotations.Measurement; import org.openjdk.jmh.annotations.Mode; import org.openjdk.jmh.annotations.OutputTimeUnit; import org.openjdk.jmh.annotations.Warmup; import de.unentscheidbar.csv2.AliasedColumns; import de.unentscheidbar.csv2.ColumnNaming; /** * {@link ColumnNaming#caseInsensitive()} and {@link ColumnNaming#weaklyCaseInsensitive()} should not be slower than * general-purpose {@link CaseInsensitiveMap}, even when dealing with ASCII-only column names. */ @BenchmarkMode(Mode.Throughput) @OutputTimeUnit(TimeUnit.MILLISECONDS) @Warmup(iterations = 10) @Measurement(iterations = 10) @Fork(1) @SuppressWarnings("javadoc") public class CaseInsensitiveBenchmark { static final String safeChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; static final Collection<String> lotsOfColumnNames = getLotsOfColumnNames(); static final String invalidKey = "_____________________________________"; @Benchmark public void ciMap() { CaseInsentiveMapData data = caseInsensitiveMapData; for (String key : data.keys.get(data.rnd.nextInt(data.keys.size()))) { if (data.map.get(key) == null) throw new AssertionError(key); } if (data.map.get(invalidKey) != null) throw new AssertionError(); } @Benchmark public void ciColumnNaming() { run(caseInsensitiveColumnNamingData); } @Benchmark public void weakCiColumnNaming() { run(weaklyCaseInsensitiveColumnNamingData); } private void run(ColumnNamingData data) { for (String key : data.keys.get(data.rnd.nextInt(data.keys.size()))) { if (data.cols.getIndex(key) == null) throw new AssertionError(key); } if (data.cols.getIndex(invalidKey) != null) throw new AssertionError(); } private static final CaseInsentiveMapData caseInsensitiveMapData = new CaseInsentiveMapData(); private static final ColumnNamingData weaklyCaseInsensitiveColumnNamingData = new ColumnNamingData( ColumnNaming.weaklyCaseInsensitive()); private static final ColumnNamingData caseInsensitiveColumnNamingData = new ColumnNamingData( ColumnNaming.caseInsensitive()); static final class ColumnNamingData { final AliasedColumns cols; final List<String[]> keys; final Random rnd = new Random(0); ColumnNamingData(ColumnNaming naming) { Map<String, Integer> temp = new HashMap<>(); keys = new ArrayList<>(); int i = 0; for (String key : lotsOfColumnNames) { temp.put(key, i); String[] variants = { key, key.toLowerCase(Locale.UK), key.toUpperCase(Locale.UK) }; keys.add(variants); } cols = new AliasedColumns(temp, temp, naming); } } static final class CaseInsentiveMapData { final CaseInsensitiveMap<String, Integer> map; final List<String[]> keys; final Random rnd = new Random(0); CaseInsentiveMapData() { this.keys = new ArrayList<>(lotsOfColumnNames.size()); this.map = new CaseInsensitiveMap<>(lotsOfColumnNames.size()); int i = 0; for (String key : lotsOfColumnNames) { map.put(key, i); String[] variants = { key, key.toLowerCase(Locale.UK), key.toUpperCase(Locale.UK) }; keys.add(variants); } } } static Collection<String> getLotsOfColumnNames() { Random rnd = new Random(0); Set<String> names = Collections.newSetFromMap(new CaseInsensitiveMap<String, Boolean>()); while (names.size() < 100) { names.add(randomString(rnd, 1 + rnd.nextInt(30))); } List<String> uniqueNames = new ArrayList<>(names); /* For predictable iteration order: */ Collections.sort(uniqueNames); Collections.shuffle(uniqueNames, rnd); return Collections.unmodifiableList(uniqueNames); } static final String randomString(Random rnd, int length) { StringBuilder b = new StringBuilder(length); for (int i = 0; i < length; i++) { b.append(safeChars.charAt(rnd.nextInt(safeChars.length()))); } return b.toString(); } }