View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0001224 | Far Manager | Editor | public | 2009-12-21 11:42 | 2010-05-15 09:04 |
Reporter | theultramage | Assigned To | alexy | ||
Priority | normal | Severity | minor | Reproducibility | always |
Status | closed | Resolution | fixed | ||
Platform | x64 | OS | Windows | OS Version | Vista SP2 |
Product Version | 2.0 | ||||
Fixed in Version | 2.0 | ||||
Summary | 0001224: copying big block of binary data causes big mem/cpu usage and heap thrashing | ||||
Description | When 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 Reproduce | Open a big binary file, hit CTRL+A, CTRL+X? | ||||
Additional Information | After 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. | ||||
Tags | No tags attached. | ||||
Build | 1554 | ||||
|
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: патч для ускорения копирования в буфер обмена, вместо перевыделения памяти для каждой строчки редактора сначала считает требуемый объем памяти, потом выделяет всю одним разом. на файле из 500k строк размером 18Мб ускоряет операцию копирования с примерно 6 минут до примерно 1 секунды. ну и вообще ассимптотика N^2 от объема файла - это в корне неверно ;) |
|
1554 |
|
вроде оно. даже, наверное, чуточку быстрее за счет ptrInitData ;) |
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 |