Speeding Up Display Time in CEditView :: MFC

kuphryn

Senior member
Jan 7, 2001
400
0
0
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
 

zephyrprime

Diamond Member
Feb 18, 2001
7,512
2
81
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.
 

zephyrprime

Diamond Member
Feb 18, 2001
7,512
2
81
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);
 

kuphryn

Senior member
Jan 7, 2001
400
0
0
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
 

singh

Golden Member
Jul 5, 2001
1,449
0
0
Why does the speed matter? If you really want it lightning quick, create your own control (it should not be very hard).
 

kuphryn

Senior member
Jan 7, 2001
400
0
0
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
 

Argo

Lifer
Apr 8, 2000
10,045
0
0
Notepad is faster because it doesn't load the entire file. Just the portion that is displayed.
 

zephyrprime

Diamond Member
Feb 18, 2001
7,512
2
81
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.
}
 

kuphryn

Senior member
Jan 7, 2001
400
0
0
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