001/* 002 * ModeShape (http://www.modeshape.org) 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.modeshape.schematic.internal.document; 017 018import static org.junit.Assert.assertNotNull; 019import static org.junit.Assert.assertTrue; 020import java.io.ByteArrayInputStream; 021import java.io.ByteArrayOutputStream; 022import java.io.IOException; 023import java.io.InputStream; 024import java.io.InputStreamReader; 025import java.io.Reader; 026import java.io.StringReader; 027import java.util.concurrent.atomic.AtomicReference; 028import org.junit.After; 029import org.junit.Before; 030import org.junit.Ignore; 031import org.junit.Test; 032import org.modeshape.schematic.document.Document; 033 034@Ignore 035public class JsonPerformanceTest { 036 037 protected JsonReader reader; 038 protected boolean print; 039 040 @Before 041 public void beforeTest() { 042 reader = new JsonReader(); 043 } 044 045 @After 046 public void afterTest() { 047 reader = null; 048 gc(); 049 } 050 051 @Test 052 public void shouldReadLargeTestDocumentWithoutDateMatching() throws Exception { 053 testReadingJson(getLargeTestData(), 200, false, false); 054 } 055 056 @Test 057 public void shouldReadLargeTestDocumentWithDateMatching() throws Exception { 058 testReadingJson(getLargeTestData(), 200, false, true); 059 } 060 061 @Test 062 public void shouldReadLargeTestDocumentWithoutDataMatchingUsingJsonSimple() throws Exception { 063 testReadingJsonWithJsonSimple(getLargeTestData(), 200, false); 064 } 065 066 @Test 067 public void shouldReadSmallTestDocumentWithoutDateMatching() throws Exception { 068 testReadingJson(getSmallTestData(), 200, false, false); 069 } 070 071 @Test 072 public void shouldReadSmallTestDocumentWithDateMatching() throws Exception { 073 testReadingJson(getSmallTestData(), 200, false, true); 074 } 075 076 @Test 077 public void shouldReadSmallTestDocumentWithoutDataMatchingUsingJsonSimple() throws Exception { 078 testReadingJsonWithJsonSimple(getSmallTestData(), 200, false); 079 } 080 081 @Test 082 public void shouldReadSmallTestDocumentToAndFromBson() throws Exception { 083 testReadingJsonThenWritingBsonThenReadingBson(getSmallTestData(), 200, false, true); 084 } 085 086 @Test 087 public static String getLargeTestData() throws Exception { 088 String result = read("sample-large-performance.json"); 089 assertTrue(result.length() != 0); 090 return result; 091 } 092 093 @Test 094 public static String getSmallTestData() throws Exception { 095 String result = read("sample-small-performance.json"); 096 assertTrue(result.length() != 0); 097 return result; 098 } 099 100 private static String read( String resourcePath ) throws IOException { 101 return read(JsonPerformanceTest.class.getClassLoader().getResourceAsStream(resourcePath)); 102 } 103 104 private static String read( InputStream stream ) throws IOException { 105 return read(new InputStreamReader(stream)); 106 } 107 108 private static String read( Reader reader ) throws IOException { 109 if (reader == null) return ""; 110 StringBuilder sb = new StringBuilder(); 111 try { 112 int numRead = 0; 113 char[] buffer = new char[1024]; 114 while ((numRead = reader.read(buffer)) > -1) { 115 sb.append(buffer, 0, numRead); 116 } 117 } finally { 118 reader.close(); 119 } 120 return sb.toString(); 121 } 122 123 private static void gc() { 124 try { 125 Thread.sleep(500L); 126 } catch (InterruptedException ie) { 127 } 128 System.gc(); 129 try { 130 Thread.sleep(500L); 131 } catch (InterruptedException ie) { 132 } 133 } 134 135 private static void runTest( String message, 136 int loops, 137 int testDataLength, 138 boolean print, 139 Runnable function ) { 140 assert loops > 0; 141 // Run several times to warm up ... 142 for (int i = 0; i != 3; ++i) { 143 function.run(); 144 } 145 long stop = 0L; 146 long start = System.nanoTime(); 147 try { 148 for (int i = 0; i != loops; ++i) { 149 function.run(); 150 } 151 } finally { 152 stop = System.nanoTime(); 153 } 154 if (print) { 155 while (message.length() < 60) 156 message = message + " "; 157 System.out.print(message + " -- data length: " + testDataLength); 158 System.out.print(" -- average time: "); 159 double delta = (stop - start) / (loops + 0D); 160 String unit = "nanos"; 161 if (delta > 1000.0) { 162 delta /= 1000000; 163 unit = "millis"; 164 } 165 System.out.println(delta + " " + unit); 166 } 167 } 168 169 protected void testReadingJson( final String testData, 170 int numberOfRuns, 171 final boolean getValue, 172 final boolean introspectStringValues ) throws Exception { 173 assertNotNull(testData); 174 final JsonReader reader = new JsonReader(); 175 final AtomicReference<Exception> error = new AtomicReference<Exception>(); 176 final String key = "key"; 177 runTest("JsonReader.read(String," + introspectStringValues + ")", numberOfRuns, testData.length(), print, new Runnable() { 178 @Override 179 public void run() { 180 try { 181 Document doc = reader.read(testData, introspectStringValues); 182 if (getValue) doc.get(key); 183 } catch (Exception t) { 184 error.compareAndSet(null, t); 185 } 186 } 187 }); 188 if (error.get() != null) throw error.get(); 189 } 190 191 protected void testReadingJsonWithJsonSimple( final String testData, 192 int numberOfRuns, 193 final boolean getValue ) throws Exception { 194 final org.json.simple.parser.JSONParser parser = new org.json.simple.parser.JSONParser(); 195 final AtomicReference<Exception> error = new AtomicReference<Exception>(); 196 final String key = "key"; 197 runTest("org.json.simple.parser.JSONParser().parse(Reader)", numberOfRuns, testData.length(), print, new Runnable() { 198 @Override 199 public void run() { 200 try { 201 org.json.simple.JSONObject obj = (org.json.simple.JSONObject)parser.parse(new StringReader(testData)); 202 if (getValue) obj.get(key); 203 } catch (Exception t) { 204 error.compareAndSet(null, t); 205 } 206 } 207 }); 208 if (error.get() != null) throw error.get(); 209 } 210 211 protected void testReadingJsonThenWritingBsonThenReadingBson( final String testData, 212 int numberOfRuns, 213 final boolean getValue, 214 final boolean introspectStringValues ) throws Exception { 215 assertNotNull(testData); 216 // Read the JSON into in-memory ... 217 Document doc = new JsonReader().read(testData, introspectStringValues); 218 219 // Write the in-memory out to BSON ... 220 ByteArrayOutputStream bytes = new ByteArrayOutputStream(); 221 new BsonWriter().write(doc, bytes); 222 final byte[] bsonBytes = bytes.toByteArray(); 223 224 final BsonReader bsonReader = new BsonReader(); 225 final AtomicReference<Exception> error = new AtomicReference<Exception>(); 226 final String key = "key"; 227 runTest("BsonReader.read(InputStream)", numberOfRuns, testData.length(), print, new Runnable() { 228 @Override 229 public void run() { 230 try { 231 ByteArrayInputStream input = new ByteArrayInputStream(bsonBytes); 232 Document doc = bsonReader.read(input); 233 doc.get(key); 234 } catch (Exception t) { 235 error.compareAndSet(null, t); 236 } 237 } 238 }); 239 if (error.get() != null) throw error.get(); 240 } 241}