diff --git a/src/saxon_pool.py b/src/saxon_pool.py index 114dd7a..0b810a4 100644 --- a/src/saxon_pool.py +++ b/src/saxon_pool.py @@ -34,7 +34,10 @@ public class SaxonWorker { // Create TransformerFactory once and reuse TransformerFactory factory = TransformerFactory.newInstance(); - System.err.println("SaxonWorker started and ready (using JAXP Transformer API)"); + // Cache für kompilierte Stylesheets (Performance-Optimierung) + Map templatesCache = new HashMap<>(); + + System.err.println("SaxonWorker started and ready (using JAXP Transformer API with stylesheet caching)"); System.err.flush(); try { @@ -66,19 +69,33 @@ public class SaxonWorker { String xslStylesheet = parts[1]; String outputFo = parts[2]; - System.err.println("DEBUG: Creating transformer from stylesheet..."); + // Prüfe ob Stylesheet bereits im Cache ist + Templates templates; + if (templatesCache.containsKey(xslStylesheet)) { + templates = templatesCache.get(xslStylesheet); + System.err.println("DEBUG: Using cached stylesheet: " + xslStylesheet); + System.err.flush(); + } else { + System.err.println("DEBUG: Compiling and caching stylesheet: " + xslStylesheet); + System.err.flush(); + + StreamSource xslSource = new StreamSource(new File(xslStylesheet)); + templates = factory.newTemplates(xslSource); + templatesCache.put(xslStylesheet, templates); + + System.err.println("DEBUG: Stylesheet compiled and cached (cache size: " + templatesCache.size() + ")"); + System.err.flush(); + } + + System.err.println("DEBUG: Creating transformer from cached template..."); System.err.flush(); // Create Source and Result objects - StreamSource xslSource = new StreamSource(new File(xslStylesheet)); StreamSource xmlSource = new StreamSource(new File(sourceXml)); StreamResult result = new StreamResult(new File(outputFo)); - System.err.println("DEBUG: Compiling stylesheet..."); - System.err.flush(); - - // Create transformer from stylesheet - Transformer transformer = factory.newTransformer(xslSource); + // Create transformer from templates + Transformer transformer = templates.newTransformer(); // Set parameters if present if (parts.length > 3 && !parts[3].isEmpty()) { diff --git a/src/saxon_pool_s9api.py b/src/saxon_pool_s9api.py index 23b622d..2f5595b 100644 --- a/src/saxon_pool_s9api.py +++ b/src/saxon_pool_s9api.py @@ -25,6 +25,8 @@ SAXON_S9API_WORKER_JAVA = """ import net.sf.saxon.s9api.*; import javax.xml.transform.stream.StreamSource; import java.io.*; +import java.util.HashMap; +import java.util.Map; public class SaxonS9ApiWorker { public static void main(String[] args) { @@ -34,7 +36,10 @@ public class SaxonS9ApiWorker { // Create Processor once and reuse (equivalent to TransformerFactory) Processor processor = new Processor(false); - System.err.println("SaxonS9ApiWorker started and ready (using s9api for XSLT 2.0/3.0)"); + // Cache für kompilierte Stylesheets (Performance-Optimierung) + Map stylesheetCache = new HashMap<>(); + + System.err.println("SaxonS9ApiWorker started and ready (using s9api for XSLT 2.0/3.0 with stylesheet caching)"); System.err.flush(); try { @@ -66,12 +71,23 @@ public class SaxonS9ApiWorker { String xslStylesheet = parts[1]; String outputFo = parts[2]; - System.err.println("DEBUG: Compiling stylesheet..."); - System.err.flush(); + // Prüfe ob Stylesheet bereits im Cache ist + XsltExecutable executable; + if (stylesheetCache.containsKey(xslStylesheet)) { + executable = stylesheetCache.get(xslStylesheet); + System.err.println("DEBUG: Using cached stylesheet: " + xslStylesheet); + System.err.flush(); + } else { + System.err.println("DEBUG: Compiling and caching stylesheet: " + xslStylesheet); + System.err.flush(); - // Compile stylesheet - XsltCompiler compiler = processor.newXsltCompiler(); - XsltExecutable executable = compiler.compile(new StreamSource(new File(xslStylesheet))); + XsltCompiler compiler = processor.newXsltCompiler(); + executable = compiler.compile(new StreamSource(new File(xslStylesheet))); + stylesheetCache.put(xslStylesheet, executable); + + System.err.println("DEBUG: Stylesheet compiled and cached (cache size: " + stylesheetCache.size() + ")"); + System.err.flush(); + } System.err.println("DEBUG: Creating transformer..."); System.err.flush(); diff --git a/src/ui/AppSettings.ui b/src/ui/AppSettings.ui index cec08c7..cc48207 100644 --- a/src/ui/AppSettings.ui +++ b/src/ui/AppSettings.ui @@ -20,7 +20,7 @@ true - 7 + 0 Qt::TextElideMode::ElideRight diff --git a/src/ui/AppSettings_ui.py b/src/ui/AppSettings_ui.py index 72ae429..86ac726 100644 --- a/src/ui/AppSettings_ui.py +++ b/src/ui/AppSettings_ui.py @@ -417,7 +417,7 @@ class Ui_Dialog(object): self.buttonBox.accepted.connect(Dialog.accept) self.buttonBox.rejected.connect(Dialog.reject) - self.tabSettings.setCurrentIndex(7) + self.tabSettings.setCurrentIndex(0) QMetaObject.connectSlotsByName(Dialog) diff --git a/src/ui/MainWindow.py b/src/ui/MainWindow.py index 4b39229..c56980f 100644 --- a/src/ui/MainWindow.py +++ b/src/ui/MainWindow.py @@ -688,11 +688,7 @@ class MainWindow(QMainWindow): # Starte Hash-Berechnung für alle XML-Dateien self._start_xml_hash_calculation() - # Initialisiere Saxon-Worker-Pool für schnellere Transformationen - self._initialize_saxon_worker_pool() - - # Initialisiere FOP-Worker-Pool für schnellere PDF-Generierung - self._initialize_fop_worker_pool() + # Worker-Pools werden jetzt erst beim Start der Transformation initialisiert (lazy loading) except Exception as e: logger.error(f"Fehler beim Laden des Projekts '{project.name}': {e}") @@ -4207,6 +4203,10 @@ class MainWindow(QMainWindow): # Zeige Progressbar self._show_transformation_progress_bar(len(jobs)) + # Initialisiere Worker-Pools (lazy loading - nur wenn benötigt) + self._initialize_saxon_worker_pool() + self._initialize_fop_worker_pool() + # Erfasse RAM-Verbrauch vor Transformation import transform @@ -4377,6 +4377,10 @@ class MainWindow(QMainWindow): if transform._fop_worker_pool: transform._fop_worker_pool.capture_ram_after_transform() + # Beende Worker-Pools (RAM-Optimierung - Pools werden bei nächster Transformation neu gestartet) + self._shutdown_saxon_worker_pool() + self._shutdown_fop_worker_pool() + # Verstecke Transformation-Progressbar self._hide_transformation_progress_bar()