• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 680
  • Last Modified:

out.println() performance

Hi!

I have a java class that constructs a large amout of html that is to be displayed on a JSP page. This html constructs a big spreadsheet-like grid, and my problem is that it seems to take soooo long time simply to print this html!?

My class Grid has a toHtml() method that returns a String (containing the HTML).

My JSP code simply looks like this (I simplified it here):

Grid grid = new Grid();
out.println(grid.toHtml());

I tried also

<%
Grid grid = new Grid();
%>
<%=grid.toHtml()%>

but same results: It takes almost 15 seconds to perform this code!!

The toHtml() method itself takes only 1,5 seconds to run, so it seems that it is the out.println() that simply works slowly here.

Can I do anything about this??

Best regards,

Nicolai
0
JNic
Asked:
JNic
2 Solutions
 
basicinstinctCommented:
can you pls post the code you use to generate the html - it seems likely to me that the problem is in there, even though you say it only take 1.5 seconds
0
 
JNicAuthor Commented:
BTW the generated html-String is really rather big. If I do:

String html = grid.toHtml();
System.out.println("Length: "+html.length());

I get:

Length: 1119833

Could it be, that it is just impossible to do faster with this size of String?

I cannot post the complete method since it is looooooooong, but look at this:

 public String toHtml() {
        double htmlStart = System.currentTimeMillis();
        double htmlStop;
        StringBuffer html = new StringBuffer();
       
        /* ALL THE STUFF THAT APPENDS TO THE HTML STRINGBUFFER
       *
       * like html.append("<html> blablablabla");
       */
 
        htmlStop = System.currentTimeMillis();
        System.out.println("Html create duration: " + (htmlStop-htmlStart)/1000 + " sec");
        return html.toString();
    }

This prints: Html create duration: 1,422 sec
0
 
TimYatesCommented:
So it takes 1.4 seconds to generate the HTML, but then it takes the browser 13 seconds to render it...

It's a browser problem then :-(  I think you will need to cut down the size of the table you are generating (add pagination to it or something), or accept the fact that it's a browser limitation :-(

Can you try another browser (firefox, etc)...  is it any quicker?

Tim
0
Learn to develop an Android App

Want to increase your earning potential in 2018? Pad your resume with app building experience. Learn how with this hands-on course.

 
pablomoralesCommented:
It could be that the browser is the one taking all that time preforming calculations on sizes for your grid data. The server does not have any control over the time the client takes to accept more data. You could test this by using wget or setting the content-disposition header to force the browser to just download the file:

response.setHeader("Content-disposition","attachment; filename=x.html");

If this is the case then you can help the browser by making the widths of your columns explicit so that it does not have to parse all the data before it starts displaying it.
0
 
TimYatesCommented:
>> making the widths of your columns explicit

That's a very good suggestion :-)

(I always forget that) ;-)

Tim
0
 
JNicAuthor Commented:
Thanks guys! :-)

I will test this in the beginning of next week.
0
 
JNicAuthor Commented:
Hi again, back on track!

Okay, I am no javascript/DHTML wizard so I might ask silly questions now - please bare with that :-)

I did not write the grid-building code, but what it generates is first the column headers, then the row headers and finally the input cells. I will give examples here:

The very beginning (and column headers):

<span class='grid' id='grid'>
<span class='colHeaders' id='colHeaders'>
<span class='colHeaderGroup' onClick='selectColumn(0)' id='col_1'>
<span class='colHeader' id='cell_0_1'>Salmonella</span>
<span class='colHeader' id='cell_1_1'>Normal</span>
<span class='colHeader' id='cell_2_1'>Primær opformering</span>
<span class='colHeader' id='cell_3_1'>Inkubator</span>
<span class='colHeader' id='cell_4_1'>1</span>
</span>
<span class='colHeaderGroup' onClick='selectColumn(1)' id='col_2'>
<span class='colHeader' id='cell_0_2'>Salmonella</span>
<span class='colHeader' id='cell_1_2'>Normal</span>
<span class='colHeader' id='cell_2_2'>Primær opformering</span>
<span class='colHeader' id='cell_3_2'>Start</span>
<span class='colHeader' id='cell_4_2'>1</span>
</span>

*
*
*

Now for the row headers:

<span class='rowHeaders' id='rowHeaders'>
<span class='rowHeaderGroup' onClick='selectRow(0)' id='row_5'>
<span class='rowHeader' id='cell_5_0'>S-060616-00172</span>
</span>
<span class='rowHeaderGroup' onClick='selectRow(1)' id='row_6'>
<span class='rowHeader' id='cell_6_0'>S-060616-00173</span>
</span>
 
*
*
*

And some input cells:

<span class='dataCells' id='dataCells' onScroll='doOnScroll()'>
<span  class='dataRow' id='row_5'>
<span class='dataCell' id='cell_5_1'><input id='0_0' name='0_0_value' value='' style=''  onKeyDown='cellKeyDown()' onChange='cellChange(this)' onContextMenu='cellContextMenu()' onMouseDown='cellMouseDown()' onFocus='cellFocus()' onBlur='cellBlur(this)' originalClassName='textFieldMandatory' class='textFieldMandatory' type='text' datatype='s' released='false' mandatory='true' ><img class='lookupButton' src='images/lookup.gif' onClick='doLookup("0_0", "Instrument")' onMouseOver='lookupOnMouseOver(this)' onMouseOut='lookupOnMouseOut(this)'></span>
<input type='hidden' id='0_0_id' name='0_0_id' value='S-060616-00172|(null)|(null)|Salmonella|1|Normal|1|Primær opformering|Inkubator|1'><input type='hidden' id='0_0_changed' name='0_0_changed' value='false'><input type='hidden' id='0_0_releasetype' name='0_0_releasetype' value=''><input type='hidden' id='0_0_units' name='0_0_units' value=''><span class='dataCell' id='cell_5_2'><input id='0_1' name='0_1_value' value='' style=''  onKeyDown='cellKeyDown()' onChange='cellChange(this)' onContextMenu='cellContextMenu()' onMouseDown='cellMouseDown()' onFocus='cellFocus()' onBlur='cellBlur(this)' originalClassName='textFieldMandatory' class='textFieldMandatory' type='text' datatype='d' released='false' mandatory='true' ><img class='lookupDateButton' src='images/lookup_date.gif' onClick='doLookupDate("0_1")' onMouseOver='lookupOnMouseOver(this)' onMouseOut='lookupOnMouseOut(this)'></span>
<input type='hidden' id='0_1_id' name='0_1_id' value='S-060616-00172|(null)|(null)|Salmonella|1|Normal|1|Primær opformering|Start|1'><input type='hidden' id='0_1_changed' name='0_1_changed' value='false'><input type='hidden' id='0_1_releasetype' name='0_1_releasetype' value=''><input type='hidden' id='0_1_units' name='0_1_units' value=''><span class='dataCell' id='cell_5_3'><input id='0_2' name='0_2_value' value='' style=''  onKeyDown='cellKeyDown()' onChange='cellChange(this)' onContextMenu='cellContextMenu()' onMouseDown='cellMouseDown()' onFocus='cellFocus()' onBlur='cellBlur(this)' originalClassName='textFieldMandatory' class='textFieldMandatory' type='text' datatype='d' released='false' mandatory='true' ><img class='lookupDateButton' src='images/lookup_date.gif' onClick='doLookupDate("0_2")' onMouseOver='lookupOnMouseOver(this)' onMouseOut='lookupOnMouseOut(this)'></span>

*
*
*

Now for your comment: >> making the widths of your columns explicit

How would I do that here? Is this information in CCS, or should I hard-code the value somewhere in this generated code?

Best regards - Nicolai
0
 
TimYatesCommented:
How many rows does this table contain once filled?

I think you're going to need to paginate it :-/

Tim
0
 
JNicAuthor Commented:
Hi,

the number of rows dependes on how many items the user selects. In this case it is max 100, but that does give quite a slow performance as discussed.

Unfortunately you might be right that it needs to be paginated, but I just wanted to hear, if there is something to gain here by "making the widths of your columns explicit" as originally suggested by pablomorales... ?
0
 
TimYatesCommented:
He means you put:

   width="100"

or whatever with you want into the <td> attributes...

That way the browser doesn't have to spend ages trying to get the table lined up, as it knows how wide everything is at the start...

Is it any faster in Firefox?

Tim
0
 
JNicAuthor Commented:
I will test this hardcoded width thing. :-)

I don't know about Firefox, if I have the time I will test that also - but it (unfortunately) not so relevant here, since the product has been sold to a customer with the restriction of using only IE :-(

I'll let you know. Thanks for your interest!!

Nic
0
 
TimYatesCommented:
Ahhhh... also, are you building up a table out of <span> objects, ie, not using a <table>?

This may be slower...I haven't tested it :-/

Tim
0
 
JNicAuthor Commented:
Yes, it was done that way by the original coder :-/

I also do not now if it is slower or what :-S
0
 
JNicAuthor Commented:
OH - Tim: sorry for not getting the point: There are NO <td 's !

So I can't explicitely set the width - or?

I boosted the points a bit since this is turning into a novel... ;-)
0
 
TimYatesCommented:
No, you cant have a "width" attribute in a span tag...  you can have one in the css styling for a span tag, but I don't think that will speed things up :-/
0
 
JNicAuthor Commented:
OK - as I see it then the last straws are breaking now :-(

In this case there is probably not much that can be done except for paginating - or maybe rewrite the whole thing into a more traditional <table>-structure (have not tested if that actually is a lot faster or not).

Or force the customer to use a limited number of items at a time, or just to live with it ;-)

Thanks for all the help!
0

Featured Post

Receive 1:1 tech help

Solve your biggest tech problems alongside global tech experts with 1:1 help.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now