/* * Copyright 2014 - 2017 Blazebit. * * 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 com.blazebit.persistence.impl.expression; import java.util.logging.Level; import java.util.logging.Logger; import org.antlr.v4.runtime.ANTLRInputStream; import org.antlr.v4.runtime.CommonTokenStream; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestRule; import com.blazebit.persistence.parser.JPQLSelectExpressionLexer; import com.blazebit.persistence.parser.JPQLSelectExpressionParser; import com.carrotsearch.junitbenchmarks.BenchmarkOptions; import com.carrotsearch.junitbenchmarks.BenchmarkRule; import org.antlr.v4.runtime.BailErrorStrategy; import org.antlr.v4.runtime.atn.PredictionMode; /** * * @author cpbec */ public class ParserPerformanceTest { private static Level originalLevel; @Rule public TestRule benchmarkRun = new BenchmarkRule(); @BeforeClass public static void beforeClass() { Logger log = Logger.getLogger("com.blazebit.persistence.parser"); originalLevel = log.getLevel(); log.setLevel(Level.OFF); } @AfterClass public static void afterClass() { Logger log = Logger.getLogger("com.blazebit.persistence.parser"); log.setLevel(originalLevel); } @BenchmarkOptions(benchmarkRounds = 10, warmupRounds = 5) @Test public void testSmallExpression() { String expression = "CONCAT(COALESCE(CONCAT(NULLIF(CONCAT(CASE WHEN LENGTH(COALESCE(buyerParty.zip,'')) > 0 OR LENGTH(COALESCE(buyerParty.city,'')) > 0 THEN COALESCE(CONCAT(NULLIF(buyerParty.street,''),', '),'') ELSE COALESCE(buyerParty.street,'') END,CASE WHEN LENGTH(COALESCE(buyerParty.city,'')) > 0 THEN COALESCE(CONCAT(NULLIF(buyerParty.zip,''),' '),'') ELSE COALESCE(buyerParty.zip,'') END,COALESCE(buyerParty.city,'')),''),' - '),''),CASE WHEN LENGTH(COALESCE(buyerParty.region.name,'')) > 0 THEN COALESCE(CONCAT(COALESCE(NULLIF(buyerParty.countryEntry.name,''),NULLIF(buyerParty.country,'')),' / '),'') ELSE COALESCE(buyerParty.countryEntry.name,buyerParty.country,'') END,COALESCE(buyerParty.region.name,''))"; doTest(expression); } @BenchmarkOptions(benchmarkRounds = 10, warmupRounds = 5) @Test public void testLargeExpression() { String expression = "CONCAT(CONCAT(buyerParty.name,CASE WHEN LENGTH(COALESCE(CONCAT(COALESCE(CONCAT(NULLIF(CONCAT(CASE WHEN LENGTH(COALESCE(buyerParty.zip,'')) > 0 OR LENGTH(COALESCE(buyerParty.city,'')) > 0 THEN COALESCE(CONCAT(NULLIF(buyerParty.street,''),', '),'') ELSE COALESCE(buyerParty.street,'') END,CASE WHEN LENGTH(COALESCE(buyerParty.city,'')) > 0 THEN COALESCE(CONCAT(NULLIF(buyerParty.zip,''),' '),'') ELSE COALESCE(buyerParty.zip,'') END,COALESCE(buyerParty.city,'')),''),' - '),''),CASE WHEN LENGTH(COALESCE(buyerParty.region.name,'')) > 0 THEN COALESCE(CONCAT(COALESCE(NULLIF(buyerParty.countryEntry.name,''),NULLIF(buyerParty.country,'')),' / '),'') ELSE COALESCE(buyerParty.countryEntry.name,buyerParty.country,'') END,COALESCE(buyerParty.region.name,'')),'')) > 0 THEN ': ' ELSE '' END),COALESCE(CONCAT(COALESCE(CONCAT(NULLIF(CONCAT(CASE WHEN LENGTH(COALESCE(buyerParty.zip,'')) > 0 OR LENGTH(COALESCE(buyerParty.city,'')) > 0 THEN COALESCE(CONCAT(NULLIF(buyerParty.street,''),', '),'') ELSE COALESCE(buyerParty.street,'') END,CASE WHEN LENGTH(COALESCE(buyerParty.city,'')) > 0 THEN COALESCE(CONCAT(NULLIF(buyerParty.zip,''),' '),'') ELSE COALESCE(buyerParty.zip,'') END,COALESCE(buyerParty.city,'')),''),' - '),''),CASE WHEN LENGTH(COALESCE(buyerParty.region.name,'')) > 0 THEN COALESCE(CONCAT(COALESCE(NULLIF(buyerParty.countryEntry.name,''),NULLIF(buyerParty.country,'')),' / '),'') ELSE COALESCE(buyerParty.countryEntry.name,buyerParty.country,'') END,COALESCE(buyerParty.region.name,'')),''))"; doTest(expression); } private void doTest(String expression) { JPQLSelectExpressionLexer l = new JPQLSelectExpressionLexer(new ANTLRInputStream(expression)); CommonTokenStream tokens = new CommonTokenStream(l); JPQLSelectExpressionParser p = new JPQLSelectExpressionParser(tokens, true, true, true); p.getInterpreter().setPredictionMode(PredictionMode.SLL); p.setErrorHandler(new BailErrorStrategy()); try { p.parseSimpleExpression(); // STAGE 1 } catch (Exception ex) { tokens.reset(); // rewind input stream p.reset(); p.getInterpreter().setPredictionMode(PredictionMode.LL); p.parseSimpleExpression(); // STAGE 2 // if we parse ok, it's LL not SLL } } }