• We’re currently investigating an issue related to the forum theme and styling that is impacting page layout and visual formatting. The problem has been identified, and we are actively working on a resolution. There is no impact to user data or functionality, this is strictly a front-end display issue. We’ll post an update once the fix has been deployed. Thanks for your patience while we get this sorted.

Speeding Up Display Time in CEditView :: MFC

kuphryn

Senior member
Hi.

I am working on a program that displays displays text similar to a text editor. The program works as expected, however, it takes a very long time to display a text file that is 60k or larger.

I am using CEditView as view. Here is the algorithm that displays the texts.

-----
int MAXSIZE = 256;
char text[MAXSIZE];
CEdit &edit = GetEditCtrl();
edit.SetWindowText("first line");
edit.GetLine(0, text, MAXSIZE); // get first line "first line"
CString newText, temp;
temp.Format("%s", text);
newText.Formate("%s%s%s", temp, "\r\n", newText);
...
-----

The concept of the algorithm is this:

1) display first line
2) get first line
3) add first line & new line in a string
4) display string
5) continue until all *new lines* are added

As you can see, this algorithm is extremely impractically. I compared it to Microsoft's Notepade. Notepage *does not* slow done until you open a file that is 1mb or larger.

Is there a better and *faster* way to display multiple lines of text while using the CEditView? Is there a way at all?

Thanks,
Kuphryn
 
You're concatenating strings essentially like:

temp.Format("%s", s1)
temp.Format("%s%s, temp, s2)
temp.Format("%s%s, temp, s3)
temp.Format("%s%s, temp, s4)
temp.Format("%s%s, temp, s5)

This is very ineffecient as temp is constantly having to have to reallocate storage space. Probably once with every call since each call except the first includes temp (this raises the overwrite self problem and may force reallocating temp).

But I don't understand your code. Why are you reading input from a CEdit control? Doesn't CEditView have a way to load in entire file? And how is text being displayed?

Maybe you should try loading the entire text file into the clipboard and then pasting that in to the CEditView. I know tat CEditView has a paste from clipboard function.
 
Oh I see, SetWindowText is overriden from CWnd and it is used to display the entire screen. Yeash. Well anyway, you can get a great speedup if you just don't bother calling SetWindowText at all for all the intermediate string and only show it once after you've concatenating the strings together.

I may be misunderstanding what you are trying to do but isn't the easiest way to do this:

GetFileAtrributes("c:\\myfile.txt", &fileinfostruct)

buffer = new char[fileinfostruct.size + some extra]
CEdit *edit = myCEditView.GetEditCtrl();

buffer[size] = '\0' //append the null character
edit->SetWindowText(buffer);
 
Thanks.

Yes. You were right about the code calling GetWindowTest() for each line. I changed it to concatenate all lines and then display it once. It is much faster now; however, Notepade is still faster. Microsoft must have used a technique where Notepage would save all lines into a data structure, but the view only displays a certain portion thus much it very fast.

New algorithm:

-----
currentData = pDoc->GetOneLine(pos++);
rE.SetWindowText(currentData);

if (pDoc->GetLineCount() > 1)
{
newData.Format("%s\r\n%s", static_cast<LPCTSTR>(currentData), pDoc->GetOneLine(pos++));

for (size_t i = 2; i < pDoc->GetLineCount(); ++i)
{
newData += "\r\n";
newData += pDoc->GetOneLine(pos++);
}

rE.SetWindowText(static_cast<LPCTSTR>(newData));
}
-----

Kuphryn
 
Why does the speed matter? If you really want it lightning quick, create your own control (it should not be very hard).
 
Thanks.

That will ultimately the best solution in the long run. I do have an edit class, however, I have not implemented features such as inserting a new line, inserting multiple lines via paste, copy, delete multiple lines, etc. It is a very basic edit class.

Kuphryn
 
You might try this to get things even faster. In the long run though, I'm not sure if you can beat notepad because it may well use some sort of fancy data structure & display mechanism like you describe. (Try CRichEdit maybe?)

1. Create a cstring that's big.
2. append strings to the cstring's buffer directly using memcpy



CString newData, currentData;
int position = 0;
LPTSTR buffer;

buffer = newData.GetBuffer( int big_number_here);


if (pDoc->GetLineCount() > 1)
{
currentData = pDoc->GetOneLine(pos++);

memcpy(buffer+position, currentData.GetBuffer(currentData.GetLength()), currentData.GetLength());

position += currentData.GetLength();
memcpy(buffer+position), "\r\n", strlen("\r\n"));
position += strlen("\r\n");
}

newData.ReleaseBuffer()
rE.SetWindowText(static_cast<LPCTSTR>(newData));


And even if you don't do this, you should at least do this:

currentData.GetBuffer(big enough number to hold entire file);
currentData.ReleaseBuffer();
{
.....the rest of the code you wrote.
}
 
Okay. Thanks.

I see your point. You mean to acquire enough member for the entire file before loading it.

I think the fact that I am dynamically allocating new memory for each new line is one part that is slowing it down. The second reason is I am using a linked list. Each time the display function calls pDoc->GetOneLine(), the program has to traverse to a position. I will fix that as soon as I have access to my computer at home. I will post an update.

Kuphryn
 
Back
Top