Solved

out.println() performance

Posted on 2006-06-16
16
654 Views
Last Modified: 2008-02-01
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
Comment
Question by:JNic
16 Comments
 
LVL 23

Expert Comment

by:basicinstinct
Comment Utility
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
 
LVL 1

Author Comment

by:JNic
Comment Utility
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
 
LVL 35

Expert Comment

by:TimYates
Comment Utility
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
 
LVL 4

Assisted Solution

by:pablomorales
pablomorales earned 100 total points
Comment Utility
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
 
LVL 35

Expert Comment

by:TimYates
Comment Utility
>> making the widths of your columns explicit

That's a very good suggestion :-)

(I always forget that) ;-)

Tim
0
 
LVL 1

Author Comment

by:JNic
Comment Utility
Thanks guys! :-)

I will test this in the beginning of next week.
0
 
LVL 1

Author Comment

by:JNic
Comment Utility
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
 
LVL 35

Expert Comment

by:TimYates
Comment Utility
How many rows does this table contain once filled?

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

Tim
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 1

Author Comment

by:JNic
Comment Utility
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
 
LVL 35

Expert Comment

by:TimYates
Comment Utility
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
 
LVL 1

Author Comment

by:JNic
Comment Utility
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
 
LVL 35

Expert Comment

by:TimYates
Comment Utility
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
 
LVL 1

Author Comment

by:JNic
Comment Utility
Yes, it was done that way by the original coder :-/

I also do not now if it is slower or what :-S
0
 
LVL 1

Author Comment

by:JNic
Comment Utility
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
 
LVL 35

Accepted Solution

by:
TimYates earned 300 total points
Comment Utility
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
 
LVL 1

Author Comment

by:JNic
Comment Utility
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

Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

Join & Write a Comment

HOW TO: Install and Configure VMware vSphere Hypervisor 6.5 (ESXi 6.5), Step by Step Tutorial with screenshots. From Download, Checking Media, to Completed Installation.
HOW TO: Connect to the VMware vSphere Hypervisor 6.5 (ESXi 6.5) using the vSphere (HTML5 Web) Host Client 6.5, and perform a simple configuration task of adding a new VMFS 6 datastore.
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…
Illustrator's Shape Builder tool will let you combine shapes visually and interactively. This video shows the Mac version, but the tool works the same way in Windows. To follow along with this video, you can draw your own shapes or download the file…

744 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now