From f002c2c53e2db568ff467e8bb037fcc761f90a26 Mon Sep 17 00:00:00 2001 From: "Charles.Lee" Date: Tue, 1 Jan 2019 17:51:16 +0900 Subject: Fast Plantuml # Test Result The example has 5 plantumls. | Test Type | Original | PLANTUML_RUN_FAST | Modify One Plantuml | |---------------------------|------------|-------------|-----------------| | Elapsed Time | 23.370 sec | 7.349 sec | 4.652 sec | | external tools Time | 23.020 sec | 6.819 sec | 4.301 sec | # Test Environments (How to test) - The example has 5 plantumls. ## Original Configration - I follow the original path to process plantuml. - Configuration of Doxyfile - OUTPUT_DIRECTORY = OUTPUT - SOURCE_BROWSER = YES - GENERATE_HTML = YES only set the html - GENERATE_LATEX = NO - Run - $ doxygen -d time ## PLANTUML_RUN_FAST - Changed Configuration of Doxyfile - PLANTUML_RUN_FAST = YES ## Modify One Plantuml - Modify one plantuml in 5 plantuml of example with the same environment of PLANTUML_RUN_TEST # How to Reduce the performance ## PLANTUML_RUN_FAST - Make Just one pu (plantuml) file to run java once - Just run once when we generate HTML. ### another test with setting YES to all GENERATE_* - When we generate several types , we run java several times according the different java arguments. - set YES to all GENERATE_* - There are 20 plantuml in this example and configuration. But, it runs java just 4 times. ```text Executing external command `java -Djava.awt.headless=true -jar "/Users/cheoljoo/bin/plantuml.jar" -o "/Users/cheoljoo/Code/github/doxygen/build/bin/B/OUTPUT/docbook" -charset UTF-8 -tpng "/Users/cheoljoo/Code/github/doxygen/build/bin/B/OUTPUT/docbook/inline_umlgraph_pngdocbook.pu" ` 10.019 sec: Running PlantUML on png PlantumlFiles in html Executing external command `java -Djava.awt.headless=true -jar "/Users/cheoljoo/bin/plantuml.jar" -o "/Users/cheoljoo/Code/github/doxygen/build/bin/B/OUTPUT/html" -charset UTF-8 -tpng "/Users/cheoljoo/Code/github/doxygen/build/bin/B/OUTPUT/html/inline_umlgraph_pnghtml.pu" ` 17.906 sec: Running PlantUML on png PlantumlFiles in rtf Executing external command `java -Djava.awt.headless=true -jar "/Users/cheoljoo/bin/plantuml.jar" -o "/Users/cheoljoo/Code/github/doxygen/build/bin/B/OUTPUT/rtf" -charset UTF-8 -tpng "/Users/cheoljoo/Code/github/doxygen/build/bin/B/OUTPUT/rtf/inline_umlgraph_pngrtf.pu" ` 25.842 sec: Running PlantUML on eps PlantumlFiles in latex Executing external command `java -Djava.awt.headless=true -jar "/Users/cheoljoo/bin/plantuml.jar" -o "/Users/cheoljoo/Code/github/doxygen/build/bin/B/OUTPUT/latex" -charset UTF-8 -teps "/Users/cheoljoo/Code/github/doxygen/build/bin/B/OUTPUT/latex/inline_umlgraph_epslatex.pu" ` ``` ## Modify One Plantuml - Cached file name : OUTPUT_DIRECTORY/inline_umlgraph_cache_all.pu - inline_umlgraph_cache_all.pu was created when doxygen was finished. - inline_umlgraph_cache_all.pu had all plantuml contents. and it will be used to check what is changed. - If you want to keep pu files , DOT_CLEANUP = NO - inline_umlgraph_.pu includes changed plantuml. So it can reduce the java processing time. # Explanation of the code ## old - generatePlantUMLOutput() makes each plantuml from each @start~enduml with the name as inline_umlgraph_#.pu. ## new (PLANTUML_RUN_FAST) - It will make a plantuml png at the end of processes of doxygen. So we can reduce the count of java runs. - class PlantumlManager saves all plantuml information for running java at the end of doxygen and for comparing the plantuml contents as a cache. - generatePlantUMLOutput() is not enough to make a database in class PlantumlManager. - So I use writePlantUMLSource() to get more information (pu name and contents). I modified writePlantUMLSource() because I do not want to read the file to get the contents in generatePlantUMLOutput(). - The writePlantUMLSource() compares each plantuml contents and filename with cached information (inline_umlgraph_cache_all.pu). Then it will decide whether will recreate or reuse. - Like dot , we make plantuml pictures at the end of doxygen. ```puml @startuml folder config.xml { artifact PLANTUML_RUN_FAST folder config.xml [ artifact xml ==== and style ] } folder debug.cpp { artifact "Debug::Plantuml" folder debug.h { artifact "Plantuml=0x4000" } } config.xml -down-> debug.cpp debug.cpp -down-> docvisitor.cpp folder docvisitor.cpp { folder writePlantUMLSource { folder writePlantUMLSource.old [ write plantuml file (inline_umlgraph_#.pu) ---- writePlantUMLFile() generatePlantUMLOutput() ] folder writePlantUMLSource.new [ write plantuml file (inline_umlgraph_#) writePlantUMLFile() generatePlantUMLOutput() ---- add PUML_Type as arguments PlantumlManager::instance()->insert(generateType,puName,format,text); ] writePlantUMLSource -down-> writePlantUMLSource.old : Original writePlantUMLSource -down-> writePlantUMLSource.new : PLANTUML_RUN_FAST } artifact docbookvisitor.cpp artifact htmldocvisitor.cpp artifact latexdocvisitor.cpp artifact rtfdocvisitor.cpp artifact vhdldocgen.cpp } database PlantumlManager.DB [ static PlantumlManager *m_theInstance; QDict< QList > m_pngPlantumlFiles; QDict< QList > m_svgPlantumlFiles; QDict< QList > m_epsPlantumlFiles; QDict< QCString > m_pngPlantumlContent; QDict< QCString > m_svgPlantumlContent; QDict< QCString > m_epsPlantumlContent; ] writePlantUMLSource.new -down-> PlantumlManager.DB : PLANTUML_RUN_FAST folder plantuml.cpp { folder generatePlantUMLOutput.old [ run java for each inline_umlgraph_#.pu ] folder generatePlantUMLOutput.new [ No run java for run once at the end of process Just add image into list ] writePlantUMLSource.old -down-> generatePlantUMLOutput.old : original writePlantUMLSource.new -down-> generatePlantUMLOutput.new : PLANTUML_RUN_FAST } folder doxygen.cpp { folder plantuml.h [ class PlantumlManager ] } folder plantuml.cpp { folder PlantumlManager_run [ PlantumlManager::instance()->run(); - run java once at the last time of doxygen process like drawing dot graph - read a inline_umlgraph_cache.pu - if exist , reuse it. - if not exist , add inline_umlgraph_type.pu - save all plantuml into inline_umlgraph_cache_all.pu for caching or reusing next time. - When we make inline_umlgraph_type.pu , we divide into 4 files for multi-processing. - But , prcessing image count is less than 8 , we will use only one file. ] } plantuml.h -down-> writePlantUMLSource : PLANTUML_RUN_FAST PlantumlManager.DB -down-> PlantumlManager_run : PLANTUML_RUN_FAST @enduml ``` --- src/plantuml.cpp | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/plantuml.cpp b/src/plantuml.cpp index 53f6125..876bf85 100644 --- a/src/plantuml.cpp +++ b/src/plantuml.cpp @@ -370,21 +370,21 @@ void PlantumlManager::runPlantumlContent(QDict< QList > &PlantumlFile if ( (format==PUML_EPS) && (Config_getBool(USE_PDFLATEX)) ) { - Debug::print(Debug::Plantuml,0,"*** %s Running epstopdf\n","PlantumlManager::runPlantumlContent"); - QList *list = PlantumlFiles[it.currentKey()]; - QListIterator li(*list); - QCString *nb; - for (li.toFirst();(nb=li.current());++li) + Debug::print(Debug::Plantuml,0,"*** %s Running epstopdf\n","PlantumlManager::runPlantumlContent"); + QList *list = PlantumlFiles[it.currentKey()]; + QListIterator li(*list); + QCString *nb; + for (li.toFirst();(nb=li.current());++li) + { + QCString epstopdfArgs(maxCmdLine); + epstopdfArgs.sprintf("\"%s%s.eps\" --outfile=\"%s%s.pdf\"",qPrint(pumlOutDir),qPrint(*nb),qPrint(pumlOutDir),qPrint(*nb)); + portable_sysTimerStart(); + if ((exitCode=portable_system("epstopdf",epstopdfArgs))!=0) { - QCString epstopdfArgs(maxCmdLine); - epstopdfArgs.sprintf("\"%s%s.eps\" --outfile=\"%s%s.pdf\"",qPrint(pumlOutDir),qPrint(*nb),qPrint(pumlOutDir),qPrint(*nb)); - portable_sysTimerStart(); - if ((exitCode=portable_system("epstopdf",epstopdfArgs))!=0) - { - err("Problems running epstopdf. Check your TeX installation! Exit code: %d\n",exitCode); - } - portable_sysTimerStop(); + err("Problems running epstopdf. Check your TeX installation! Exit code: %d\n",exitCode); } + portable_sysTimerStop(); + } } } } -- cgit v0.12