summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCharles.Lee <cheoljoo@gmail.com>2018-08-27 03:14:55 (GMT)
committerCharles.Lee <cheoljoo@gmail.com>2018-08-27 03:14:55 (GMT)
commit1a9bb0614362217143d8e01779d8ac9b336b96f4 (patch)
tree36ec658ef5ab1530ea8d4a18fb6f7b7c8cafe656
parent94a52469b177703d3e0d94bed6c4a48bddba18cb (diff)
downloadDoxygen-1a9bb0614362217143d8e01779d8ac9b336b96f4.zip
Doxygen-1a9bb0614362217143d8e01779d8ac9b336b96f4.tar.gz
Doxygen-1a9bb0614362217143d8e01779d8ac9b336b96f4.tar.bz2
Imporvement of performance : Reduce the Java running count
# What is it - #6465 is the first reqeust. So I followed up the albert advice. - in case of debug you use printf statements, I think that here there better options would be - create an -d flag (e.g. -d plantuml) that gives the information, so no need for using the configuration option - Follow up : create -d plantuml [debug.h, debug.cpp] - usage of printf - printf should not be used,all output is steered over calls to routines as defined in message.cpp, - Follow up : use Debug::Print(Debug::Plantuml, ... and msg() - usage of std::string / std::map - in doxygen the string manipulation is. mostly, done by means of Qt classes (e.g. classes QCString, QString). For consistency these classes should be used. - map manipulation is also done by means of Qt classes (dictionary and list classes) - Follow up : use QDict QList QCString [plantuml.h, plantuml.cpp] - dirent / opendir /readdir - when browsing through directories the routines line readFileOrDirectory should probably be used or the techniques used in this routine - Follow up : I will follow when I try to reduce redundancy of creating plantuml image. - Run java minimally - Test Case : 4 plantuml - Original Run without PLANTUML_RUN_JAVA_ONCE - 8.2 sec = 4 times * ( 1.6(java vm) + 0.1 * 1(load multiple file) + process each plantuml (0.35) *1 ) <- prediction - New with PLANTUML_RUN_JAVA_ONCE - 3.499 sec = 1.6(java vm) + 0.1 * 4(load multiple file) + process each plantuml (0.35) *4 <- prediction - Creating Java Virtual Machine has a big portion. - Result - Improving Performance : 8.2 -> 3.499 (in case of 4 plantuml) # Configuration - add configuration value in Doxyfile - PLANTUML_RUN_JAVA_ONCE = YES # Debugging - doxygen -d plantuml - doxygen -d time -d plantuml # Tested with following options - source code of 3 plantuml - PLANTUML_RUN_JAVA_ONCE = YES or NO - DOT_IMAGE_FORMAT = png or svg - DOT_CLEANUP = YES or NO - -d plantuml
-rw-r--r--src/config.xml8
-rw-r--r--src/debug.cpp1
-rw-r--r--src/debug.h3
-rw-r--r--src/doxygen.cpp8
-rw-r--r--src/plantuml.cpp238
-rw-r--r--src/plantuml.h22
6 files changed, 267 insertions, 13 deletions
diff --git a/src/config.xml b/src/config.xml
index 2e0f430..4af0a65 100644
--- a/src/config.xml
+++ b/src/config.xml
@@ -3491,6 +3491,14 @@ to be found in the default search path.
]]>
</docs>
</option>
+ <option type='bool' id='PLANTUML_RUN_JAVA_ONCE' defval='0'>
+ <docs>
+<![CDATA[
+If the \c PLANTUML_RUN_JAVA_ONCE tag is set to \c YES, doxygen will run java once for improving the performance.
+This will run once at the end of process like dot graphics processing.
+]]>
+ </docs>
+ </option>
<option type='int' id='DOT_GRAPH_MAX_NODES' minval='0' maxval='10000' defval='50' depends='HAVE_DOT'>
<docs>
<![CDATA[
diff --git a/src/debug.cpp b/src/debug.cpp
index c81a1af..2f343ac 100644
--- a/src/debug.cpp
+++ b/src/debug.cpp
@@ -48,6 +48,7 @@ static LabelMap s_labels[] =
{ "markdown", Debug::Markdown },
{ "filteroutput", Debug::FilterOutput },
{ "lex", Debug::Lex },
+ { "plantuml", Debug::Plantuml },
{ 0, (Debug::DebugMask)0 }
};
diff --git a/src/debug.h b/src/debug.h
index 8a28c7a..9a2070c 100644
--- a/src/debug.h
+++ b/src/debug.h
@@ -37,7 +37,8 @@ class Debug
ExtCmd = 0x00000400,
Markdown = 0x00000800,
FilterOutput = 0x00001000,
- Lex = 0x00002000
+ Lex = 0x00002000,
+ Plantuml = 0x00004000
};
static void print(DebugMask mask,int prio,const char *fmt,...);
static int setFlag(const char *label);
diff --git a/src/doxygen.cpp b/src/doxygen.cpp
index bf93a9b..b33ae49 100644
--- a/src/doxygen.cpp
+++ b/src/doxygen.cpp
@@ -103,6 +103,7 @@
#include "settings.h"
#include "context.h"
#include "fileparser.h"
+#include "plantuml.h"
// provided by the generated file resources.cpp
extern void initResources();
@@ -11707,6 +11708,13 @@ void generateOutput()
g_s.end();
}
+ if (Config_getBool(PLANTUML_RUN_JAVA_ONCE))
+ {
+ g_s.begin("Running plantuml with JAVA...\n");
+ PlantumlManager::instance()->run();
+ g_s.end();
+ }
+
if (Config_getBool(HAVE_DOT))
{
g_s.begin("Running dot...\n");
diff --git a/src/plantuml.cpp b/src/plantuml.cpp
index ada035b..feac907 100644
--- a/src/plantuml.cpp
+++ b/src/plantuml.cpp
@@ -19,8 +19,11 @@
#include "doxygen.h"
#include "index.h"
#include "message.h"
+#include "debug.h"
#include <qdir.h>
+#include <qdict.h>
+#include <qlist.h>
static const int maxCmdLine = 40960;
@@ -29,6 +32,9 @@ QCString writePlantUMLSource(const QCString &outDir,const QCString &fileName,con
QCString baseName(4096);
static int umlindex=1;
+ Debug::print(Debug::Plantuml,0,"*** %s fileName: %s\n",__PRETTY_FUNCTION__,qPrint(fileName));
+ Debug::print(Debug::Plantuml,0,"*** %s outDir: %s\n",__PRETTY_FUNCTION__,qPrint(outDir));
+
if (fileName.isEmpty()) // generate name
{
baseName = outDir+"/inline_umlgraph_"+QCString().setNum(umlindex++);
@@ -40,6 +46,8 @@ QCString writePlantUMLSource(const QCString &outDir,const QCString &fileName,con
if (i!=-1) baseName = baseName.left(i);
baseName.prepend(outDir+"/");
}
+
+ Debug::print(Debug::Plantuml,0,"*** %s baseName: %s\n",__PRETTY_FUNCTION__,qPrint(baseName));
QFile file(baseName+".pu");
if (!file.open(IO_WriteOnly))
{
@@ -55,9 +63,9 @@ QCString writePlantUMLSource(const QCString &outDir,const QCString &fileName,con
void generatePlantUMLOutput(const char *baseName,const char *outDir,PlantUMLOutputFormat format)
{
- static QCString plantumlJarPath = Config_getString(PLANTUML_JAR_PATH);
- static QCString plantumlConfigFile = Config_getString(PLANTUML_CFG_FILE);
- static QCString dotPath = Config_getString(DOT_PATH);
+ QCString plantumlJarPath = Config_getString(PLANTUML_JAR_PATH);
+ QCString plantumlConfigFile = Config_getString(PLANTUML_CFG_FILE);
+ QCString dotPath = Config_getString(DOT_PATH);
QCString pumlExe = "java";
QCString pumlArgs = "";
@@ -123,17 +131,39 @@ void generatePlantUMLOutput(const char *baseName,const char *outDir,PlantUMLOutp
pumlArgs+=".pu\" ";
pumlArgs+="-charset UTF-8 ";
int exitCode;
- //printf("*** running: %s %s outDir:%s %s\n",pumlExe.data(),pumlArgs.data(),outDir,baseName);
msg("Running PlantUML on generated file %s.pu\n",baseName);
portable_sysTimerStart();
- if ((exitCode=portable_system(pumlExe,pumlArgs,TRUE))!=0)
- {
- err("Problems running PlantUML. Verify that the command 'java -jar \"%splantuml.jar\" -h' works from the command line. Exit code: %d\n",
- plantumlJarPath.data(),exitCode);
- }
- else if (Config_getBool(DOT_CLEANUP))
- {
- QFile(QCString(baseName)+".pu").remove();
+ if(Config_getBool(PLANTUML_RUN_JAVA_ONCE)){
+ //Debug::print(Debug::Plantuml,0,"*** imgName %s\n",qPrint(imgName));
+ //Debug::print(Debug::Plantuml,0,"*** running: %s %s outDir:%s %s\n",qPrint(pumlExe),qPrint(pumlArgs),outDir,baseName);
+ //Debug::print(Debug::Plantuml,0,"*** baseName: %s\n",baseName);
+ //Debug::print(Debug::Plantuml,0,"*** outDir: %s\n",outDir);
+ //Debug::print(Debug::Plantuml,0,"*** project name: %s\n",qPrint(Config_getString(PROJECT_NAME)) );
+ //Debug::print(Debug::Plantuml,0,"*** output directory: %s\n",qPrint(Config_getString(OUTPUT_DIRECTORY)) );
+ QCString qcOutDir(outDir);
+ uint pos = qcOutDir.findRev("/");
+ //Debug::print(Debug::Plantuml,0,"*** right: %d\n",pos );
+ //QCString baseDirectoryName(qcOutDir.left(pos));
+ //Debug::print(Debug::Plantuml,0,"*** baseDirectoryName: %s\n",qPrint(baseDirectoryName));
+ QCString generateType(qcOutDir.right(qcOutDir.length() - (pos + 1)) );
+ Debug::print(Debug::Plantuml,0,"*** %s generateType: %s\n",__PRETTY_FUNCTION__,qPrint(generateType));
+ QCString qcBaseName(baseName);
+ pos = qcBaseName.findRev("/");
+ //Debug::print(Debug::Plantuml,0,"*** right: %d\n",pos );
+ QCString baseFileName(qcBaseName.right(qcBaseName.length() - (pos + 1)) );
+ Debug::print(Debug::Plantuml,0,"*** %s baseFileName: %s\n",__PRETTY_FUNCTION__,qPrint(baseFileName));
+ PlantumlManager::instance()->insert(generateType,baseFileName,format);
+ } else { // ! Config_getBool(PLANTUML_RUN_JAVA_ONCE)
+ Debug::print(Debug::Plantuml,0,"*** running: %s %s outDir:%s %s\n",qPrint(pumlExe),qPrint(pumlArgs),outDir,baseName);
+ if ((exitCode=portable_system(pumlExe,pumlArgs,TRUE))!=0)
+ {
+ err("Problems running PlantUML. Verify that the command 'java -jar \"%splantuml.jar\" -h' works from the command line. Exit code: %d\n",
+ plantumlJarPath.data(),exitCode);
+ }
+ else if (Config_getBool(DOT_CLEANUP))
+ {
+ QFile(QCString(baseName)+".pu").remove();
+ }
}
portable_sysTimerStop();
if ( (format==PUML_EPS) && (Config_getBool(USE_PDFLATEX)) )
@@ -150,3 +180,187 @@ void generatePlantUMLOutput(const char *baseName,const char *outDir,PlantUMLOutp
Doxygen::indexList->addImageFile(imgName);
}
+//--------------------------------------------------------------------
+
+PlantumlManager *PlantumlManager::m_theInstance = 0;
+
+PlantumlManager *PlantumlManager::instance()
+{
+ if (!m_theInstance)
+ {
+ m_theInstance = new PlantumlManager;
+ }
+ return m_theInstance;
+}
+
+PlantumlManager::PlantumlManager()
+{
+}
+
+PlantumlManager::~PlantumlManager()
+{
+ {
+ QDictIterator< QList<QCString> > it( m_pngPlantumlFiles); // See QDictIterator
+ QList<QCString> *list;
+ for (it.toFirst();(list=it.current());++it)
+ {
+ (*list).clear();
+ }
+ m_pngPlantumlFiles.clear();
+ }
+}
+
+void PlantumlManager::runPlantumlFiles(QDict< QList <QCString> > &PlantumlFiles,const char *type)
+{
+ /* *** running: java -Djava.awt.headless=true -jar "/Users/cheoljoo/code/common_telltale/GP/Apps/Src/MgrTelltale/tools/plantuml.jar" -o "/Users/cheoljoo/Code/LG/test_doxygen/DOXYGEN_OUTPUT/html" -tpng "/Users/cheoljoo/Code/LG/test_doxygen/DOXYGEN_OUTPUT/html/A.pu" -charset UTF-8 outDir:/Users/cheoljoo/Code/LG/test_doxygen/DOXYGEN_OUTPUT/html /Users/cheoljoo/Code/LG/test_doxygen/DOXYGEN_OUTPUT/html/A
+ */
+ int exitCode;
+ QCString plantumlJarPath = Config_getString(PLANTUML_JAR_PATH);
+ QCString plantumlConfigFile = Config_getString(PLANTUML_CFG_FILE);
+ QCString dotPath = Config_getString(DOT_PATH);
+
+ QCString pumlExe = "java";
+ QCString pumlArgs = "";
+
+ QStrList &pumlIncludePathList = Config_getList(PLANTUML_INCLUDE_PATH);
+ char *s=pumlIncludePathList.first();
+ if (s)
+ {
+ pumlArgs += "-Dplantuml.include.path=\"";
+ pumlArgs += s;
+ s = pumlIncludePathList.next();
+ }
+ while (s)
+ {
+ pumlArgs += portable_pathListSeparator();
+ pumlArgs += s;
+ s = pumlIncludePathList.next();
+ }
+ if (pumlIncludePathList.first()) pumlArgs += "\" ";
+ pumlArgs += "-Djava.awt.headless=true -jar \""+plantumlJarPath+"plantuml.jar\" ";
+ if (!plantumlConfigFile.isEmpty())
+ {
+ pumlArgs += "-config \"";
+ pumlArgs += plantumlConfigFile;
+ pumlArgs += "\" ";
+ }
+ if (Config_getBool(HAVE_DOT) && !dotPath.isEmpty())
+ {
+ pumlArgs += "-graphvizdot \"";
+ pumlArgs += dotPath;
+ pumlArgs += "dot";
+ pumlArgs += portable_commandExtension();
+ pumlArgs += "\" ";
+ }
+
+
+ QDictIterator< QList<QCString> > it( PlantumlFiles); // See QDictIterator
+ QList<QCString> *list;
+ for (it.toFirst();(list=it.current());++it)
+ {
+ QCString pumlArguments(pumlArgs);
+ msg("Running PlantUML on png PlantumlFiles in %s\n",qPrint(it.currentKey()));
+ pumlArguments+="-o \"";
+ pumlArguments+=Config_getString(OUTPUT_DIRECTORY);
+ pumlArguments+="/";
+ pumlArguments+=it.currentKey();
+ pumlArguments+="\" ";
+ pumlArguments+="-charset UTF-8 ";
+ pumlArguments+=type;
+ pumlArguments+=" ";
+ QListIterator<QCString> li(*list);
+ QCString *nb;
+ for (li.toFirst();(nb=li.current());++li)
+ {
+ pumlArguments+="\"";
+ pumlArguments+=Config_getString(OUTPUT_DIRECTORY);
+ pumlArguments+="/";
+ pumlArguments+=it.currentKey();
+ pumlArguments+="/";
+ pumlArguments+=*nb;
+ pumlArguments+=".pu";
+ pumlArguments+="\" ";
+ }
+ Debug::print(Debug::Plantuml,0,"*** %s Running Plantuml arguments:%s\n",__PRETTY_FUNCTION__,qPrint(pumlArguments));
+ if ((exitCode=portable_system(pumlExe,pumlArguments,TRUE))!=0)
+ {
+ err("Problems running PlantUML. Verify that the command 'java -jar \"%splantuml.jar\" -h' works from the command line. Exit code: %d\n",
+ plantumlJarPath.data(),exitCode);
+ }
+ else if (Config_getBool(DOT_CLEANUP))
+ {
+ for (li.toFirst();(nb=li.current());++li)
+ {
+ QCString pumlName = "";
+ pumlName+=Config_getString(OUTPUT_DIRECTORY);
+ pumlName+="/";
+ pumlName+=it.currentKey();
+ pumlName+="/";
+ pumlName+=*nb;
+ pumlName+=".pu";
+ QFile(pumlName).remove();
+ }
+ }
+ }
+
+}
+
+void PlantumlManager::run()
+{
+ Debug::print(Debug::Plantuml,0,"*** %s\n",__PRETTY_FUNCTION__);
+ runPlantumlFiles(m_pngPlantumlFiles, "-tpng");
+ runPlantumlFiles(m_svgPlantumlFiles, "-tsvg");
+ runPlantumlFiles(m_epsPlantumlFiles, "-teps");
+}
+
+void PlantumlManager::print(QDict< QList <QCString> > &PlantumlFiles)
+{
+ if (Debug::isFlagSet(Debug::Plantuml)){
+ QDictIterator< QList<QCString> > it( PlantumlFiles); // See QDictIterator
+ QList<QCString> *list;
+ for (it.toFirst();(list=it.current());++it)
+ {
+ Debug::print(Debug::Plantuml,0,"*** %s PlantumlFiles key:%s\n",__PRETTY_FUNCTION__,qPrint(it.currentKey()));
+ QListIterator<QCString> li(*list);
+ QCString *nb;
+ for (li.toFirst();(nb=li.current());++li)
+ {
+ Debug::print(Debug::Plantuml,0,"*** %s PlantumlFiles list:%s\n",__PRETTY_FUNCTION__,qPrint(*nb));
+ }
+ }
+ }
+}
+
+void PlantumlManager::addPlantumlFiles(QDict< QList <QCString> > &PlantumlFiles,const QCString key , const QCString value)
+{
+ QList<QCString> *list = PlantumlFiles.find(key);
+ if (list==0)
+ {
+ list = new QList<QCString>;
+ PlantumlFiles.insert(key,list);
+ }
+ list->append(new QCString(value));
+ Debug::print(Debug::Plantuml,0,"*** %s append : png key:%s ,value:%s\n",__PRETTY_FUNCTION__,qPrint(key),qPrint(value));
+}
+
+void PlantumlManager::insert(const QCString key , const QCString value, PlantUMLOutputFormat format)
+{
+ Debug::print(Debug::Plantuml,0,"*** %s key:%s ,value:%s\n",__PRETTY_FUNCTION__,qPrint(key),qPrint(value));
+ switch (format)
+ {
+ case PUML_BITMAP:
+ addPlantumlFiles(m_pngPlantumlFiles,key,value);
+ print(m_pngPlantumlFiles);
+ break;
+ case PUML_EPS:
+ addPlantumlFiles(m_epsPlantumlFiles,key,value);
+ print(m_epsPlantumlFiles);
+ break;
+ case PUML_SVG:
+ addPlantumlFiles(m_svgPlantumlFiles,key,value);
+ print(m_svgPlantumlFiles);
+ break;
+ }
+}
+
+//--------------------------------------------------------------------
diff --git a/src/plantuml.h b/src/plantuml.h
index 54ab8a2..b931e70 100644
--- a/src/plantuml.h
+++ b/src/plantuml.h
@@ -16,6 +16,9 @@
#ifndef PLANTUML_H
#define PLANTUML_H
+#include <qdict.h>
+#include <qlist.h>
+
class QCString;
/** Plant UML output image formats */
@@ -36,5 +39,24 @@ QCString writePlantUMLSource(const QCString &outDir,const QCString &fileName,con
*/
void generatePlantUMLOutput(const char *baseName,const char *outDir,PlantUMLOutputFormat format);
+/** Singleton that manages plantuml relation actions */
+class PlantumlManager
+{
+ public:
+ static PlantumlManager *instance();
+ void run();
+ void insert(const QCString key , const QCString value,PlantUMLOutputFormat format);
+ private:
+ PlantumlManager();
+ virtual ~PlantumlManager();
+ void addPlantumlFiles(QDict< QList <QCString> > &PlantumlFiles,const QCString key , const QCString value);
+ void print(QDict< QList <QCString> > &PlantumlFiles);
+ void runPlantumlFiles(QDict< QList <QCString> > &PlantumlFiles,const char *type);
+ static PlantumlManager *m_theInstance;
+ QDict< QList<QCString> > m_pngPlantumlFiles;
+ QDict< QList<QCString> > m_svgPlantumlFiles;
+ QDict< QList<QCString> > m_epsPlantumlFiles;
+};
+
#endif