package org.wikibrain.matrix; import gnu.trove.map.TIntIntMap; import gnu.trove.map.hash.TIntIntHashMap; import org.apache.commons.io.FileUtils; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.IntBuffer; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel; import java.util.Arrays; import java.util.Random; /** * @author Shilad Sen */ public class BenchBuffers { public static final int NUM_INTS = 4000000; public static final int NUM_ITERATIONS = 100; public static void main(String args[]) throws IOException { File tmpFile = File.createTempFile("tmp", "bytes"); tmpFile.deleteOnExit(); Random random = new Random(); int ints[] = new int[NUM_INTS]; for (int i = 0; i < ints.length; i++) { ints[i] = random.nextInt(); } Arrays.sort(ints); ByteBuffer byteBuffer = ByteBuffer.allocate(ints.length * 4); IntBuffer intBuffer = byteBuffer.asIntBuffer(); intBuffer.put(ints); FileUtils.writeByteArrayToFile(tmpFile, byteBuffer.array()); for (int i = 0; i < 10; i++) { timeArray(ints); } for (int i = 0; i < 10; i++) { timeBuffer(tmpFile); } for (int i = 0; i < 10; i++) { timeHashSearches(ints); } for (int i = 0; i < 10; i++) { timeBufferSearches(tmpFile); } for (int i = 0; i < 10; i++) { timeBinarySearches(ints); } tmpFile.delete(); } public static void timeArray(int[] ints) { long before = System.currentTimeMillis(); long total = 0; for (int t = 0; t < NUM_ITERATIONS; t++) { for (int i = 0; i < ints.length; i++) { if (ints[i] > Integer.MIN_VALUE) { total++; } } } long after = System.currentTimeMillis(); System.err.println("array ops per milli is " + 1.0 * total / (after - before)); } public static void timeBuffer(File file) throws IOException { FileChannel channel = (new FileInputStream(file)).getChannel(); long size = channel.size(); MappedByteBuffer buffer = channel.map(FileChannel.MapMode.READ_ONLY, 0, size); IntBuffer ints = buffer.asIntBuffer(); long before = System.currentTimeMillis(); long total = 0; for (int t = 0; t < NUM_ITERATIONS; t++) { for (int i = 0; i < ints.capacity(); i++) { if (ints.get(i) > Integer.MIN_VALUE) { total++; } } } long after = System.currentTimeMillis(); System.err.println("buffer ops per milli is " + 1.0 * total / (after - before)); } public static void timeBinarySearches(int [] ints) { long before = System.currentTimeMillis(); long hits = 0; for (int i = 0; i < NUM_INTS; i++) { int goal = ints[Math.abs(i * 3571) % ints.length]; int lo = 0; int hi = ints.length - 1; while (lo <= hi) { int mid = (lo + hi) / 2; int midId = ints[mid]; if (goal < midId) { hi = mid - 1; } else if (goal > midId) { lo = mid + 1; } else { hits++; break; } } } long after = System.currentTimeMillis(); System.err.println("array searchers per milli is " + 1.0 * (NUM_INTS) / (after - before) + " with " + hits + " hits"); } public static void timeBufferSearches(File file) throws IOException { FileChannel channel = (new FileInputStream(file)).getChannel(); long size = channel.size(); MappedByteBuffer buffer = channel.map(FileChannel.MapMode.READ_ONLY, 0, size); IntBuffer ints = buffer.asIntBuffer(); long before = System.currentTimeMillis(); long hits = 0; int n = ints.capacity(); for (int i = 0; i < NUM_INTS; i++) { int goal = ints.get(Math.abs(i * 3571) % n); int lo = 0; int hi = n - 1; while (lo <= hi) { int mid = (lo + hi) / 2; int midId = ints.get(mid); if (goal < midId) { hi = mid - 1; } else if (goal > midId) { lo = mid + 1; } else { hits++; break; } } } long after = System.currentTimeMillis(); System.err.println("buffer searchers per milli is " + 1.0 * (NUM_INTS) / (after - before) + " with " + hits + " hits"); } private static void timeHashSearches(int[] ints) { TIntIntMap indexes = new TIntIntHashMap(ints.length); for (int i = 0; i < ints.length; i++) { indexes.put(ints[i], i); } long before = System.currentTimeMillis(); long hits = 0; for (int i = 0; i < NUM_INTS; i++) { int goal = ints[Math.abs(i * 3571) % ints.length]; if (indexes.get(goal) > 0) { hits++; } } long after = System.currentTimeMillis(); System.err.println("hash searchers per milli is " + 1.0 * (NUM_INTS) / (after - before) + " with " + hits + " hits"); } }