View Issue Details

IDProjectCategoryView StatusLast Update
0008126ScribusUser Interfacepublic2009-07-12 15:46
Reportermecirt Assigned Tocbradney  
PrioritynormalSeverityminorReproducibilityalways
Status closedResolutionfixed 
Platformx86-64OSLinux 
Product Version1.5.0svn 
Fixed in Version1.5.0svn 
Summary0008126: Paste is slow, as well as duplicate (patch attached)
DescriptionThe paste operation (including the duplicate and multiple duplicate ones) is rather slow in scribus currently. I have investigated the issue, and it turns out that the reason is that the Serializer object, which is used to implement paste functionality by converting to XML and back, it created anew for each paste operation. This means that the finite-state automaton is also recreated each time, which is a very expensive operation.

I am attaching a patch which reuses a single Serializer object, resetting each instead before each use, which fixes the problem and speeds up paste and duplication operations significantly.
TagsNo tags attached.
Patch

Activities

2009-06-07 17:32

 

scribus-paste-speedup.patch (5,362 bytes)   
Index: scribus/serializer.cpp
===================================================================
--- scribus/serializer.cpp	(revision 13657)
+++ scribus/serializer.cpp	(working copy)
@@ -281,6 +281,7 @@
 
 Selection Serializer::deserializeObjects(const QByteArray & xml)
 {
+	reset();
 	backUpColors = m_Doc.PageColors;
 	store<ScribusDoc>("<scribusdoc>", &m_Doc);
 
@@ -291,6 +292,7 @@
 
 Selection Serializer::deserializeObjects(const QFile & file)
 {
+	reset();
 	backUpColors = m_Doc.PageColors;
 	store<ScribusDoc>("<scribusdoc>", &m_Doc);
 
Index: scribus/scribusdoc.cpp
===================================================================
--- scribus/scribusdoc.cpp	(revision 13657)
+++ scribus/scribusdoc.cpp	(working copy)
@@ -129,6 +129,7 @@
 	m_ScMW(0),
 	m_View(0),
 	m_guardedObject(this),
+	m_serializer(NULL),
 	is12doc(false),
 	NrItems(0),
 	First(1), Last(0),
@@ -238,6 +239,7 @@
 	m_ScMW(0),
 	m_View(0),
 	m_guardedObject(this),
+	m_serializer(NULL),
 	is12doc(false),
 	NrItems(0),
 	First(1), Last(0),
@@ -515,6 +517,7 @@
 	}
 	if (docHyphenator)
 		delete docHyphenator;
+	delete m_serializer;
 }
 
 
@@ -10864,3 +10867,10 @@
 	}
 	return namesMap;
 }
+
+Serializer *ScribusDoc::serializer()
+{
+	if (!m_serializer) m_serializer = new Serializer (*this);
+	return m_serializer;
+}
+
Index: scribus/scribusview.cpp
===================================================================
--- scribus/scribusview.cpp	(revision 13657)
+++ scribus/scribusview.cpp	(working copy)
@@ -2229,7 +2229,7 @@
 		bool savedAlignGrid = Doc->useRaster;
 		bool savedAlignGuides = Doc->SnapGuides;
 		QByteArray fragment   = ScMimeData::clipboardScribusFragment();
-		Selection pastedObjects = Serializer(*Doc).deserializeObjects(fragment);
+		Selection pastedObjects = Doc->serializer()->deserializeObjects(fragment);
 		Doc->useRaster = savedAlignGrid;
 		Doc->SnapGuides = savedAlignGuides;
 		pastedObjects.setGroupRect();
Index: scribus/scribusdoc.h
===================================================================
--- scribus/scribusdoc.h	(revision 13657)
+++ scribus/scribusdoc.h	(working copy)
@@ -69,6 +69,7 @@
 class PageSize;
 class ScPattern;
 class UndoTransaction;
+class Serializer;
 
 class QProgressBar;
 
@@ -889,7 +890,9 @@
 	void scaleGroup(double scx, double scy, bool scaleText=true, Selection* customSelection = 0);
 	//! \brief Get a list of frames of certain type
 	QMap<PageItem*, QString> getDocItemNames(PageItem::ItemType itemType);
-	
+	//! \brief Returns a serializer for this document
+	Serializer *serializer();
+
 protected:
 	void addSymbols();
 	bool m_hasGUI;
@@ -906,6 +909,7 @@
 	ScribusMainWindow* m_ScMW;
 	ScribusView* m_View;
 	ScGuardedObject<ScribusDoc> m_guardedObject;
+	Serializer *m_serializer;
 	
 public: // Public attributes
 	bool is12doc; //public for now, it will be removed later
Index: scribus/scribus.cpp
===================================================================
--- scribus/scribus.cpp	(revision 13657)
+++ scribus/scribus.cpp	(working copy)
@@ -5016,9 +5016,9 @@
 			// debug:
 			SaxXML tmpfile1("tmp-scribus1.xml", true);
 			Serializer::serializeObjects(*doc->m_Selection, tmpfile1);
-			Serializer digester(*doc);
+			Serializer *digester = doc->serializer();
 			QFile file ("tmp-scribus1.xml");
-			Selection objects = digester.deserializeObjects(file);
+			Selection objects = digester->deserializeObjects(file);
 			SaxXML tmpfile2("tmp-scribus2.xml", true);
 			Serializer::serializeObjects(objects, tmpfile2);
 			doc->itemSelection_DeleteItem(&objects);
@@ -5067,7 +5067,7 @@
 
 			if (ScMimeData::clipboardHasScribusText())
 			{
-				Serializer dig(*doc);
+				Serializer dig(*doc); // TODO: do we really need a new serializer here?
 				dig.store<ScribusDoc>("<scribusdoc>", doc);
 				StoryText::desaxeRules("/", dig, "SCRIBUSTEXT");
 				dig.addRule("/SCRIBUSTEXT", desaxe::Result<StoryText>());
@@ -5105,7 +5105,7 @@
 				else
 				{
 					QByteArray fragment = ScMimeData::clipboardScribusFragment();
-					Serializer(*doc).deserializeObjects(fragment);
+					doc->serializer()->deserializeObjects(fragment);
 				}
 
 				// update style lists:
@@ -5192,7 +5192,7 @@
 				else
 				{
 					QByteArray fragment = ScMimeData::clipboardScribusFragment();
-					Selection pastedObjects = Serializer(*doc).deserializeObjects(fragment);
+					Selection pastedObjects = doc->serializer()->deserializeObjects(fragment);
 					for (int i=0; i < pastedObjects.count(); ++i)
 						pastedObjects.itemAt(i)->LayerNr = doc->activeLayer();
 
Index: scribus/desaxe/digester.cpp
===================================================================
--- scribus/desaxe/digester.cpp	(revision 13657)
+++ scribus/desaxe/digester.cpp	(working copy)
@@ -135,6 +135,14 @@
 	state->addRule(pattern, action);
 }
 
+void Digester::reset()
+{
+	objects.clear();
+	storage.clear();
+	result_.ptr = NULL;
+	result_.type = "";
+	errors.clear();
+}
 
 void Digester::beginDoc()
 {
Index: scribus/desaxe/digester.h
===================================================================
--- scribus/desaxe/digester.h	(revision 13657)
+++ scribus/desaxe/digester.h	(working copy)
@@ -102,6 +102,7 @@
 	Digester();
 	Digester& operator=(const Digester& other);
 	virtual ~Digester();
+	void reset();
 	void addRule(const Xml_string& pattern, Action action);
 	
 	void parseFile(const Xml_string& filename);
scribus-paste-speedup.patch (5,362 bytes)   

avox

2009-06-07 17:53

administrator   ~0021899

great!

christoph_s

2009-06-09 00:06

administrator   ~0021906

Actually, I don't see much of a speed improvement. Morover, right-click+drag is still extremeley slow. It takes ages until the triggered dialog shows up.

jghali

2009-06-09 08:18

administrator   ~0021909

christoph_s : the specific issue described and targeted by mecirt patch is fixed and right-click+drag is out of scope of this issue

Issue History

Date Modified Username Field Change
2009-06-07 17:32 mecirt New Issue
2009-06-07 17:32 mecirt File Added: scribus-paste-speedup.patch
2009-06-07 17:53 avox Note Added: 0021899
2009-06-07 21:50 christoph_s Status new => assigned
2009-06-07 21:50 christoph_s Assigned To => cbradney
2009-06-08 13:27 cbradney Status assigned => resolved
2009-06-08 13:27 cbradney Fixed in Version => 1.5.0svn
2009-06-08 13:27 cbradney Resolution open => fixed
2009-06-09 00:06 christoph_s Note Added: 0021906
2009-06-09 00:06 christoph_s Status resolved => feedback
2009-06-09 00:06 christoph_s Resolution fixed => reopened
2009-06-09 08:18 jghali Note Added: 0021909
2009-06-09 08:18 jghali Status feedback => resolved
2009-06-09 08:18 jghali Resolution reopened => fixed
2009-07-12 15:46 cbradney Status resolved => closed