View Issue Details

IDProjectCategoryView StatusLast Update
0001224Far ManagerEditorpublic2010-05-15 09:04
Reportertheultramage Assigned Toalexy  
PrioritynormalSeverityminorReproducibilityalways
Status closedResolutionfixed 
Platformx64OSWindowsOS VersionVista SP2
Product Version2.0 
Fixed in Version2.0 
Summary0001224: copying big block of binary data causes big mem/cpu usage and heap thrashing
DescriptionWhen I open a 40MB rar file in the text editor, highlight some 30MB from it, and do CTRL+X, it takes several minutes at max cpu load and 250MB of allocated memory until the operation completes. While it is running, mem usage jumps up and down by ~50MB.
Steps To ReproduceOpen a big binary file, hit CTRL+A, CTRL+X?
Additional InformationAfter attaching a debugger, I found execution in editor.cpp, function Editor::Block2Text(). When I examined the line "wchar_t *NewPtr=(wchar_t *)xf_realloc(CopyData,(DataSize+Length+2)*sizeof(wchar_t));", I found that it was reallocating 50 megabytes.

It might be possible that the code works very well for normal text. I did not analyze it, and therefore can't say whether it's good or not. But my test case seems to indicate that it might not be written in an efficient way.
TagsNo tags attached.
Build1554

Activities

alexfh

2010-05-13 14:12

reporter  

editor.cpp.patch (1,099 bytes)   
Index: editor.cpp
===================================================================
--- editor.cpp	(revision 4649)
+++ editor.cpp	(working copy)
@@ -4022,6 +4022,28 @@
 		DataSize = StrLength(CopyData);
 	}
 
+	int TotalChars = DataSize;
+	for (Edit *Ptr=BlockStart; Ptr!=nullptr; Ptr=Ptr->m_next)
+	{
+		int Length=Ptr->GetLength()+1;
+		TotalChars += Length + 2;
+	}
+
+	wchar_t *NewPtr=(wchar_t *)xf_realloc(CopyData,TotalChars*sizeof(wchar_t));
+
+	if (NewPtr==nullptr)
+	{
+		if (CopyData)
+		{
+			xf_free(CopyData);
+			CopyData=nullptr;
+		}
+
+		return CopyData;
+	}
+
+	CopyData=NewPtr;
+
 	Edit *CurPtr=BlockStart;
 
 	while (CurPtr!=nullptr)
@@ -4033,20 +4055,6 @@
 		if (StartSel==-1)
 			break;
 
-		wchar_t *NewPtr=(wchar_t *)xf_realloc(CopyData,(DataSize+Length+2)*sizeof(wchar_t));
-
-		if (NewPtr==nullptr)
-		{
-			if (CopyData)
-			{
-				xf_free(CopyData);
-				CopyData=nullptr;
-			}
-
-			break;
-		}
-
-		CopyData=NewPtr;
 		CurPtr->GetSelString(CopyData+DataSize,Length);
 		DataSize+=StrLength(CopyData+DataSize);
 
editor.cpp.patch (1,099 bytes)   

alexfh

2010-05-13 14:13

reporter   bugnote:0005357

editor.cpp.patch:

патч для ускорения копирования в буфер обмена, вместо перевыделения памяти для каждой строчки редактора сначала считает требуемый объем памяти, потом выделяет всю одним разом.
на файле из 500k строк размером 18Мб ускоряет операцию копирования с примерно 6 минут до примерно 1 секунды.
ну и вообще ассимптотика N^2 от объема файла - это в корне неверно ;)

alexy

2010-05-14 15:00

administrator   bugnote:0005369

1554

alexfh

2010-05-15 08:33

reporter   bugnote:0005372

вроде оно. даже, наверное, чуточку быстрее за счет ptrInitData ;)

Issue History

Date Modified Username Field Change
2009-12-21 11:42 theultramage New Issue
2010-02-15 16:54 alexy Status new => assigned
2010-02-15 16:54 alexy Assigned To => alexy
2010-05-13 14:12 alexfh File Added: editor.cpp.patch
2010-05-13 14:13 alexfh Note Added: 0005357
2010-05-14 15:00 alexy Note Added: 0005369
2010-05-14 15:00 alexy Status assigned => feedback
2010-05-15 08:33 alexfh Note Added: 0005372
2010-05-15 09:04 alexy Build => 1554
2010-05-15 09:04 alexy Status feedback => closed
2010-05-15 09:04 alexy Resolution open => fixed
2010-05-15 09:04 alexy Fixed in Version => 2.0