Is JasperReports 10 times faster than Birt?

12,117

Solution 1

After reading similar discussions and completing my evaluation I think in most cases Birt is actually much slower than Jasper. There are things to do in order to make it faster, but they cost time at the moment, whereas Jasper already gives a good performance for basic reporting needs. I don't know if it could perform better than Jasper in case I set it up better or optimized the code or the report template, but in most similar cases I read on internet discussions people just accept this performance and leave it as it is. Here is an example of an issue at the openMRS which closed unsolved: https://tickets.openmrs.org/browse/BIRT-30

I hope the following image doesn't downvote me, but I was really tempted to post it. I also thought to send it to my boss as an answer to the evaluation, but I'd rather not:

Jasper Birt Evaluation

Solution 2

If somebody need it...

Java application on Intel i3 with 4cores 5Gb. Oracle database server.

Similar report template for jasper and birt that makes 20 requests to database and 20 sub-requests (subreports).

Goal: Generate 6000 pdf documents in 30 threads ( 200 documents per thread ).

QA:

  • why birt 2.6.2?
    • we are using it currently and we compared it to 4.5 - no real benefits for us.
    • birt 4.+ makes call to getParameterMetaData() that is not implemented in oracle ojdbc6 and partially in ojdbc7 and just slows down execution
  • why 2.6.2 patched?
    • there is a problem in birt 2.+ and 3.+ and maybe in later versions: all dataset parameters evaluated through javascript and parsed/compiled versions of those scripts are not cached. described here. Evaluated JS columns are perfectly cached in ReportRunnable.
  • Why Jasper with Continuation Subreport Runner?
    • Continuation Subreport Runner (described here) runs all subreports in thread of the main report thread. By default jasper 6.2 uses ThreadPoolSubreportRunnerFactory that (i think by mistake) holds all previously retrieved data in the memory until full GC executed and it starts enormous number of threads.

results

Solution 3

The engine is designed to be reused. You should create it once, then run 10 reports. The engine loads a lot of classes when the first reports runs - later runs will be much faster. Also, the engine caches fonts. Your test setup is not fair.

Solution 4

I think it is because you create and destroy a BIRT report engine on each run. You should initialize a report engine only once, and keep it for example in a static variable of a class for next report generations. This will be much faster

Share:
12,117
Stefanos Kargas
Author by

Stefanos Kargas

Senior Software Engineer Started as a pure desktop developer. Deeply valuing object oriented programming and organized coding according to standards and fundamentals. Currently working full-stack eager to learn new technologies and keep updated to new standards. Java, C# (.Net), Visual Basic (.Net), PHP Spring Framework, MVC, Laravel PostgreSQL, MyPHP, SQL Server, Oracle HTML, CSS, JS, Angular

Updated on June 26, 2022

Comments

  • Stefanos Kargas
    Stefanos Kargas almost 2 years

    I am doing an evaluation of JasperReports and Birt reporting engines.

    I designed a simple report in both tools where I give 20 values to the report as parameters and fill 6 other values from an SQL selection in the report as detail relation (this means that I have many rows of them).
    I programmed the creation of both reports in Java and the PDF export (I think both reporting engines use iText)
    I measured the time each report needed. The reports are exactly the same and they are ran from the same process.
    The report was ran for 10 sets of values. So I measured the time for each of the 10 reports. The result was:

    Printing Jasper reports for 10 values. Measuring time needed. 110 109 141 125 110 125 110 125 109 110 Jasper Finished!!!

    Printing Birt reports for 10 values. Measuring time needed. 1063 1017 1095 1079 1063 1079 1048 1064 1079 1080 Birt Finished!!!

    The numbers are in msecs.

    Is it possible that Jasper is 10 times faster than Birt. Am I doing something wrong with my code that slows things down for Birt? I am posting the code I used in each case:

    JasperReports:

    // Export Jasper report
    long startTime = System.currentTimeMillis();
    JasperPrint myJasperPrint;
    JRExporter myJRExporter = new net.sf.jasperreports.engine.export.JRPdfExporter();
    try {
        myJRExporter.setParameter(JRExporterParameter.OUTPUT_FILE_NAME, "C:/Workspace/myProject/jasperReport" + reportNr + ".pdf");
        myJasperPrint = JasperFillManager.fillReport("C:/Workspace/myProject/reports/testReport.jasper", jasperParametersMap, connection);
        myJRExporter.setParameter(JRExporterParameter.JASPER_PRINT, myJasperPrint);
        myJRExporter.exportReport();
        return (System.currentTimeMillis() - startTime);
    } catch (JRException ex) {
        System.out.println(ex);
    }
    

    Birt:

    // Export Birt report
    String format = HTMLRenderOption.OUTPUT_FORMAT_PDF;
    EngineConfig config = new EngineConfig();
    config.setEngineHome("C:\\Tools\\Eclipse\\plugins\\org.eclipse.birt.report.viewer_4.2.2.v201302041142\\birt");
    HTMLEmitterConfig hc = new HTMLEmitterConfig();
    HTMLCompleteImageHandler imageHandler = new HTMLCompleteImageHandler();
    hc.setImageHandler(imageHandler);
    config.setEmitterConfiguration(HTMLRenderOption.OUTPUT_FORMAT_HTML, hc);
    ReportEngine engine = new ReportEngine(config);
    IReportRunnable report = null;
    String reportFilepath = "C:/Workspace/EntireJ/Besuchblatt/reports/new_report.rptdesign";
    HTMLRenderOption options = new HTMLRenderOption();
    options.setOutputFormat(format);
    options.setOutputFileName("C:/Workspace/myProject/birtReport" + reportNr + ".pdf");
    long startTime = System.currentTimeMillis();
    try {
        report = engine.openReportDesign(reportFilepath);
    }
    catch (EngineException e) {
        System.err.println("Report " + reportFilepath + " not found!\n");
        engine.destroy( );
        return;
    }
    IRunAndRenderTask task = engine.createRunAndRenderTask(report);
    task.setRenderOption(options);
    task.setParameterValues(parametersMap);
    try {
        task.run();
        return (System.currentTimeMillis() - startTime);
    }
    catch ( EngineException e1 ) {
        System.err.println( "Report " + reportFilepath + " run failed.\n");
        System.err.println( e1.toString( ) );
    }
    engine.destroy( );
    

    Is there a way to optimize Birt's performance in my case?