View Issue Details

IDProjectCategoryView StatusLast Update
0001921Far ManagerEditorpublic2013-02-28 08:05
ReporterMaximus Assigned Tovskirdin  
PrioritynormalSeverityminorReproducibilityhave not tried
Status closedResolutionfixed 
Product Version3.0 
Summary0001921: Нереальные тормоза в ECTL_ADDCOLOR
DescriptionЕсли длина строки оказывается достаточно большой - фар практически зависает.
Например, если строка 400K и включен colorer, то дождаться окончания перехода в конец строки невозможно.

После предлагаемых оптимизаций скорость приблизилась к той, что была в Far2. Быстрее видимо никак - стало больше данных для обработки.

PS. 400K строки это вполне реальные примеры, например для xml файлов.
Additional InformationОсновной overhead был из-за того, что сортировка вызывалась на _каждый_ ECTL_ADDCOLOR, что приводило к печальным результатам.
Кроме того, на каждое обновление строки весь ColorList сначала освобождался, а потом под него опять по чуть-чуть выделялась память (realloc +16), что тоже кушает процессор.
TagsNo tags attached.
Build2358

Activities

Maximus

2011-11-13 12:31

reporter  

ECTL_ADDCOLOR.111113.diff (8,029 bytes)   
Index: editor.hpp
===================================================================
--- editor.hpp	(revision 6877)
+++ editor.hpp	(working copy)
@@ -213,6 +213,9 @@
 
 		FileEditor *HostFileEditor;
 
+		int SortColorLockCount;
+		bool SortColorUpdate;
+
 	private:
 		virtual void DisplayObject();
 		void ShowEditor(int CurLineOnly);
@@ -395,4 +398,7 @@
 		void GetCursorType(bool& Visible, DWORD& Size);
 		void SetObjectColor(PaletteColors Color,PaletteColors SelColor);
 		void DrawScrollbar();
+		void SortColorLock();
+		void SortColorUnlock();
+		bool SortColorLocked();
 };
Index: editor.cpp
===================================================================
--- editor.cpp	(revision 6877)
+++ editor.cpp	(working copy)
@@ -94,7 +94,9 @@
 	StackPos(0),
 	NewStackPos(FALSE),
 	EditorID(::EditorID++),
-	HostFileEditor(nullptr)
+	HostFileEditor(nullptr),
+	SortColorLockCount(0),
+	SortColorUpdate(false)
 {
 	_KEYMACRO(SysLog(L"Editor::Editor()"));
 	_KEYMACRO(SysLog(1));
@@ -350,7 +352,9 @@
 				if (!Flags.Check(FEDITOR_DIALOGMEMOEDIT))
 				{
 					_SYS_EE_REDRAW(SysLog(L"Call ProcessEditorEvent(EE_REDRAW,EEREDRAW_CHANGE)"));
+					SortColorLock();
 					CtrlObject->Plugins.ProcessEditorEvent(EE_REDRAW,EEREDRAW_CHANGE);
+					SortColorUnlock();
 				}
 			}
 			else
@@ -358,7 +362,9 @@
 				if (!Flags.Check(FEDITOR_DIALOGMEMOEDIT))
 				{
 					_SYS_EE_REDRAW(SysLog(L"Call ProcessEditorEvent(EE_REDRAW,%s)",(CurLineOnly?"EEREDRAW_LINE":"EEREDRAW_ALL")));
+					SortColorLock();
 					CtrlObject->Plugins.ProcessEditorEvent(EE_REDRAW,CurLineOnly?EEREDRAW_LINE:EEREDRAW_ALL);
+					SortColorUnlock();
 				}
 			}
 		}
@@ -2750,7 +2756,9 @@
 						CtrlObject->Plugins.CurEditor=HostFileEditor; // this;
 						//_D(SysLog(L"%08d EE_REDRAW",__LINE__));
 						_SYS_EE_REDRAW(SysLog(L"Editor::ProcessKey[%d](!EdOpt.CursorBeyondEOL): EE_REDRAW(EEREDRAW_ALL)",__LINE__));
+						SortColorLock();
 						CtrlObject->Plugins.ProcessEditorEvent(EE_REDRAW,EEREDRAW_ALL);
+						SortColorUnlock();
 					}
 
 					/*$ 03.02.2001 SKV
@@ -3040,7 +3048,9 @@
 			{
 				CtrlObject->Plugins.CurEditor=HostFileEditor; // this;
 				_SYS_EE_REDRAW(SysLog(L"Editor::ProcessMouse[%08d] ProcessEditorEvent(EE_REDRAW,EEREDRAW_LINE)",__LINE__));
+				SortColorLock();
 				CtrlObject->Plugins.ProcessEditorEvent(EE_REDRAW,EEREDRAW_LINE);
+				SortColorUnlock();
 			}
 		}
 
@@ -5867,7 +5877,8 @@
 					return FALSE;
 				}
 
-				CurPtr->AddColor(&newcol);
+				CurPtr->AddColor(&newcol,SortColorLocked());
+				SortColorUpdate=true;
 				return TRUE;
 			}
 
@@ -5926,7 +5937,8 @@
 					return FALSE;
 				}
 
-				return(CurPtr->DeleteColor(col->StartPos,col->Owner));
+				SortColorUpdate=true;
+				return(CurPtr->DeleteColor(col->StartPos,col->Owner,SortColorLocked()));
 			}
 
 			break;
@@ -7114,3 +7126,28 @@
 		XX2=X2-(ScrollBarEx(X2,Y1,Y2-Y1+1,NumLine-CalcDistance(TopScreen,CurLine,-1),NumLastLine)?1:0);
 	}
 }
+
+void Editor::SortColorLock()
+{
+	SortColorLockCount++;
+}
+
+void Editor::SortColorUnlock()
+{
+	if (SortColorLockCount > 0)
+		SortColorLockCount--;
+	else
+		SortColorLockCount = 0;
+
+	if (SortColorLockCount == 0 && SortColorUpdate)
+	{
+		Edit* CurPtr;
+		for (CurPtr=TopList; CurPtr; CurPtr=CurPtr->m_next)
+			CurPtr->SortColorUnlocked();
+	}
+}
+
+bool Editor::SortColorLocked()
+{
+	return (SortColorLockCount > 0);
+}
Index: edit.hpp
===================================================================
--- edit.hpp	(revision 6877)
+++ edit.hpp	(working copy)
@@ -140,6 +140,9 @@
 		wchar_t *Mask;
 		ColorItem *ColorList;
 		int    ColorCount;
+		int    MaxColorCount;
+		bool   ColorListNeedSort;
+		bool   ColorListNeedFree;
 
 		FarColor Color;
 		FarColor SelColor;
@@ -277,8 +280,9 @@
 
 		void  InsertTab();
 
-		void  AddColor(ColorItem *col);
-		int   DeleteColor(int ColorPos,const GUID& Owner);
+		void  AddColor(ColorItem *col,bool skipsort=false);
+		void  SortColorUnlocked();
+		int   DeleteColor(int ColorPos,const GUID& Owner,bool skipfree=false);
 		int   GetColor(ColorItem *col,int Item);
 
 		void Xlat(bool All=false);
Index: edit.cpp
===================================================================
--- edit.cpp	(revision 6877)
+++ edit.cpp	(working copy)
@@ -98,7 +98,8 @@
 	SetObjectColor(COL_COMMANDLINE, COL_COMMANDLINESELECTED);
 	EndType=EOL_NONE;
 	ColorList=nullptr;
-	ColorCount=0;
+	ColorCount=MaxColorCount=0;
+	ColorListNeedSort=ColorListNeedFree=false;
 	TabSize=Opt.EdOpt.TabSize;
 	TabExpandMode = EXPAND_NOTABS;
 	Flags.Change(FEDITLINE_DELREMOVESBLOCKS,Opt.EdOpt.DelRemovesBlocks);
@@ -2599,18 +2600,80 @@
 	return item1->SubPriority - item2->SubPriority;
 }
 
-void Edit::AddColor(ColorItem *col)
+void Edit::AddColor(ColorItem *col,bool skipsort)
 {
-	if (!(ColorCount & 15))
-		ColorList=(ColorItem *)xf_realloc(ColorList,(ColorCount+16)*sizeof(*ColorList));
+	if (ColorCount==MaxColorCount)
+	{
+		if (ColorCount<256)
+		{
+			if (!(ColorCount & 15))
+			{
+				MaxColorCount=ColorCount+16;
+				ColorList=(ColorItem *)xf_realloc(ColorList,(MaxColorCount)*sizeof(*ColorList));
+			}
+		}
+		else if (ColorCount<2048)
+		{
+			if (!(ColorCount & 255))
+			{
+				MaxColorCount=ColorCount+256;
+				ColorList=(ColorItem *)xf_realloc(ColorList,(MaxColorCount)*sizeof(*ColorList));
+			}
+		}
+		else if (ColorCount<65536)
+		{
+			if (!(ColorCount & 2047))
+			{
+				MaxColorCount=ColorCount+2048;
+				ColorList=(ColorItem *)xf_realloc(ColorList,(MaxColorCount)*sizeof(*ColorList));
+			}
+		}
+		else if (!(ColorCount & 65535))
+		{
+			MaxColorCount=ColorCount+65536;
+			ColorList=(ColorItem *)xf_realloc(ColorList,(MaxColorCount)*sizeof(*ColorList));
+		}
+	}
 
+	#ifdef _DEBUG
+	_ASSERTE(ColorCount<MaxColorCount);
+	#endif
+
+	if (skipsort && !ColorListNeedSort && ColorCount && ColorList[ColorCount-1].Priority>col->Priority)
+		ColorListNeedSort=true;
+
 	ColorList[ColorCount++]=*col;
-	for(int ii=0;ii<ColorCount;++ii) ColorList[ii].SubPriority=ii;
-	far_qsort(ColorList,ColorCount,sizeof(*ColorList),SortColors);
+
+	if (!skipsort)
+	{
+		for(int ii=0;ii<ColorCount;++ii) ColorList[ii].SubPriority=ii;
+		far_qsort(ColorList,ColorCount,sizeof(*ColorList),SortColors);
+	}
 }
 
-int Edit::DeleteColor(int ColorPos,const GUID& Owner)
+void Edit::SortColorUnlocked()
 {
+	if (ColorListNeedFree)
+	{
+		ColorListNeedFree=false;
+		if (!ColorCount)
+		{
+			xf_free(ColorList);
+			ColorList=nullptr;
+			MaxColorCount = 0;
+		}
+	}
+
+	if (ColorListNeedSort)
+	{
+		ColorListNeedSort=false;
+		for(int ii=0;ii<ColorCount;++ii) ColorList[ii].SubPriority=ii;
+		far_qsort(ColorList,ColorCount,sizeof(*ColorList),SortColors);
+	}
+}
+
+int Edit::DeleteColor(int ColorPos,const GUID& Owner,bool skipfree)
+{
 	int Src;
 
 	if (!ColorCount)
@@ -2618,22 +2681,48 @@
 
 	int Dest=0;
 
-	for (Src=0; Src<ColorCount; Src++)
-		if ((ColorPos!=-1 && ColorList[Src].StartPos!=ColorPos) || (!IsEqualGUID(Owner,ColorList[Src].Owner)))
+	if (ColorPos!=-1)
+	{
+		for (Src=0; Src<ColorCount; Src++)
 		{
-			if (Dest!=Src)
-				ColorList[Dest]=ColorList[Src];
+			if ((ColorList[Src].StartPos!=ColorPos) || (!IsEqualGUID(Owner,ColorList[Src].Owner)))
+			{
+				if (Dest!=Src)
+					ColorList[Dest]=ColorList[Src];
 
-			Dest++;
+				Dest++;
+			}
 		}
+	}
+	else
+	{
+		for (Src=0; Src<ColorCount; Src++)
+		{
+			if (!IsEqualGUID(Owner,ColorList[Src].Owner))
+			{
+				if (Dest!=Src)
+					ColorList[Dest]=ColorList[Src];
 
+				Dest++;
+			}
+		}
+	}
+
 	int DelCount=ColorCount-Dest;
 	ColorCount=Dest;
 
 	if (!ColorCount)
 	{
-		xf_free(ColorList);
-		ColorList=nullptr;
+		if (skipfree)
+		{
+			ColorListNeedFree=true;
+		}
+		else
+		{
+			xf_free(ColorList);
+			ColorList=nullptr;
+			MaxColorCount = 0;
+		}
 	}
 
 	return(DelCount);
ECTL_ADDCOLOR.111113.diff (8,029 bytes)   

vskirdin

2012-01-10 11:55

administrator   bugnote:0008344

build 2358

Issue History

Date Modified Username Field Change
2011-11-13 12:31 Maximus New Issue
2011-11-13 12:31 Maximus File Added: ECTL_ADDCOLOR.111113.diff
2012-01-10 11:55 vskirdin Note Added: 0008344
2012-01-10 11:55 vskirdin Assigned To => vskirdin
2012-01-10 11:55 vskirdin Status new => feedback
2013-02-28 08:05 vskirdin Build => 2358
2013-02-28 08:05 vskirdin Status feedback => closed
2013-02-28 08:05 vskirdin Resolution open => fixed