zoukankan      html  css  js  c++  java
  • Druid VS Antlr4

    DRUID VS ANTLR4

    测试方法

    环境:x86_64,eclipse kepler,jdk 6
    测试对象:antlr v4,druid手写sql parser模块
    测试过程:分别采用单线程、多线程并发测试。单线程时,比较antlr、druid各自解析1次同一条sql语句的性能;多线程(50线程)时,比较antlr、druid所有线程完成1次同一条sql解析的性能。

    测试结果##

    类别 单线程(druid比antlr) 多线程(druid比antlr)
    简单select7倍6倍
    复杂select 约200倍 约1600倍
    Insert 6倍 11倍
    Update 15倍 13倍
    Delete 3倍 4倍

    总结##

    1、性能:druid好于antlr。
    2、语法支持:两者皆可实现各类语法,但antlr易于druid实现。目前发现druid没有完全实现pg语法,如int ‘123’类型转换。
    3、可维护性:antlr好于druid 特别是体现在新增语法时,修改druid的工作量大于antlr。
    4、可读性:antlr好于druid antlr采用独立的语法文件管理语法规则,druid语法规则与代码耦合。
    5、关键字支持:两者皆支持。druid需要使用switch语句块穷举。


    package com.laudandjolynn.test;
    
    import java.text.NumberFormat;
    import java.util.concurrent.Callable;
    import java.util.concurrent.CompletionService;
    import java.util.concurrent.ExecutorCompletionService;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    import org.apache.commons.cli.BasicParser;
    import org.apache.commons.cli.CommandLine;
    import org.apache.commons.cli.CommandLineParser;
    import org.apache.commons.cli.Options;
    
    import com.alibaba.druid.sql.dialect.postgresql.parser.PGSQLStatementParser;
    import com.laudandjolynn.idb.AntlrParser;
    
    public class SqlParser {
    	private final static String ANTLR = "ANTLR";
    	private final static String DRUID = "DRUID";
    
    	public static void main(String[] args) throws Exception {
    		CommandLineParser clp = new BasicParser();
    		Options options = new Options();
    		options.addOption("t", true, "");
    		options.addOption("m", true, "");
    		options.addOption("p", true, "");
    		options.addOption("s", true, "");
    		CommandLine cl = clp.parse(options, args);
    		String helpMsg = "usage: java -jar test.jar -t {antlr|druid} [-m times] [-p threads] -s sql";
    		if (!cl.hasOption('t') || !cl.hasOption('s')) {
    			System.out.println(helpMsg);
    			System.exit(0);
    		}
    
    		String tool = cl.getOptionValue('t');
    		String sql = cl.getOptionValue('s');
    		int threadCount = cl.hasOption('p') ? Integer.valueOf(cl
    				.getOptionValue('p')) : 1;
    		int executeTimes = cl.hasOption('m') ? Integer.valueOf(cl
    				.getOptionValue('m')) : 1;
    		if (threadCount == 1) {
    			single(1, sql, tool, false);
    			single(executeTimes, sql, tool, true);
    		} else {
    			multiple(1, sql, tool, 1, false);
    			multiple(executeTimes, sql, tool, threadCount, true);
    		}
    		System.exit(0);
    	}
    
    	private static void single(int executeTimes, String sql, String tool,
    			boolean stat) {
    		long sum = 0;
    		long max = Long.MIN_VALUE;
    		long min = Long.MAX_VALUE;
    		int maxIndex = -1;
    		for (int j = 0; j < executeTimes; j++) {
    			long start = System.nanoTime();
    			parse(sql, tool);
    			long elapse = System.nanoTime() - start;
    			if (max < elapse) {
    				max = elapse;
    				maxIndex = j;
    			}
    			if (min > elapse) {
    				min = elapse;
    			}
    			sum += elapse;
    		}
    		if (stat) {
    			NumberFormat format = NumberFormat.getInstance();
    			format.setMaximumFractionDigits(3);
    			System.out.println("max: " + format.format(max / 1000000.0)
    					+ " ms. max value index: " + maxIndex);
    			System.out
    					.println("min: " + format.format(min / 1000000.0) + " ms");
    			System.out.println("avg: "
    					+ format.format(sum / (double) executeTimes / 1000000.0)
    					+ " ms");
    		}
    	}
    
    	private static void multiple(int executeTimes, String sql, String tool,
    			int threadCount, boolean stat) throws Exception {
    		ExecutorService executorService = Executors
    				.newFixedThreadPool(threadCount);
    		CompletionService<Long[]> completionService = new ExecutorCompletionService<Long[]>(
    				executorService);
    		for (int i = 0; i < threadCount; i++) {
    			completionService.submit(new Parser(executeTimes, sql, tool));
    		}
    
    		long sum = 0;
    		long max = Long.MIN_VALUE;
    		long min = Long.MAX_VALUE;
    		int maxIndex = -1;
    		for (int i = 0; i < threadCount; i++) {
    			Long[] elapses = completionService.take().get();
    			for (int j = 0; j < executeTimes; j++) {
    				if (max < elapses[j]) {
    					max = elapses[j];
    					maxIndex = i * j;
    				}
    				if (min > elapses[j]) {
    					min = elapses[j];
    				}
    				sum += elapses[j];
    			}
    		}
    
    		if (stat) {
    			NumberFormat format = NumberFormat.getInstance();
    			format.setMaximumFractionDigits(3);
    			System.out.println("max: " + format.format(max / 1000000.0)
    					+ " ms. max value index: " + maxIndex);
    			System.out
    					.println("min: " + format.format(min / 1000000.0) + " ms");
    			System.out.println("avg: "
    					+ format.format(sum / executeTimes / threadCount
    							/ 1000000.0) + " ms");
    		}
    	}
    
    	private static class Parser implements Callable<Long[]> {
    		private String sql = null;
    		private String tool = null;
    		private int executeTimes;
    
    		public Parser(int executeTimes, String sql, String tool) {
    			this.executeTimes = executeTimes;
    			this.sql = sql;
    			this.tool = tool;
    		}
    
    		@Override
    		public Long[] call() throws Exception {
    			Long result[] = new Long[executeTimes];
    			for (int i = 0; i < executeTimes; i++) {
    				long start = System.nanoTime();
    				parse(sql, tool);
    				result[i] = System.nanoTime() - start;
    			}
    			return result;
    		}
    	}
    
    	private static void parse(String sql, String tool) {
    		if (ANTLR.equalsIgnoreCase(tool)) {
    			AntlrParser.parse(sql);
    		} else if (DRUID.equalsIgnoreCase(tool)) {
    			new PGSQLStatementParser(sql).parseStatement();
    		}
    	}
    }
  • 相关阅读:
    关于SDK-manager中我们需要下载哪些?
    不只是撸代码搞鸡汤,也有故事!
    [Selenium]如何通过Selenium实现Ctrl+click,即按住Ctrl的同时进行单击操作
    【设计模式】单例模式
    【Java多线程】线程池学习
    【leetcode】147 Insertion Sort List
    【webssh】shellinabox搭建
    【SpringMVC】一次处理项目中文乱码的经历
    【Java多线程】JUC包下的工具类CountDownLatch、CyclicBarrier和Semaphore
    【leetcode】3 SUM
  • 原文地址:https://www.cnblogs.com/laud/p/antlr_vs_druid.html
Copyright © 2011-2022 走看看