Hallo,
I combined Snippet7 and Snippet4 for a preview of a scaled grid.
When I have tables with 20 columns and 620 rows the preview works only for the first 3 pages. The preview hangs by page 4.
On the otherside I can print the hole document.
I get the same problem, when I use BigPrint instead of ScalePrint.
I don't have this preview-problem with smaller tables.
I'am using Eclispe Version: 3.2.0 Build-ID: M20070212-1330
Tristan
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The huge number of TextPrints is causing you to run out of operating system graphics resources. i.e. with 20 columns and 620 rows, and a font and foreground color allocated for each cell, you are allocating 24800 resources just for that document.
I have implemented a resource pool that shares Font and Color instances on a per device basis. Please check out the latest sources from SVN, run your snippet again, and let me know if that fixes your problem.
Matthew
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I'm having the same issue, but with much larger table. I've got about 8 or 9 columns with about 3500 rows. Print preview takes a long time to load (minutes). I have the latest source. Is there any way to speed it up?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The problem is that PrintPreview wants to lay out the entire document before displaying pages. This is so that PageNumberPrints can display the correct total page count, which is not known until you lay out all pages.
An approach I've been considering was to use an iterator for getting pages in a print job, rather than the current approach which gets an array. Pages would only be generated as needed. However this requires that you use a different page number format which would not show the total page count (since it's inaccurate).
To prevent breaking backward compatibility, we would have to add a property (probably to PrintJob) which indicates that the document should do layout one page at a time.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I was actually thinking the same thing. Would there be any other means of determining the number of total pages without doing a full render? I'm currently previewing small lists (< 100 rows), and they aren't fast (no offence). This is simply 3 pages worth of data. When we get to the 300-400 row range, we notice a lot of latency.
I don't want to sound like I'm slandering your work, because so far I think it's great...and I appreciate your efforts.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Facts don't offend me. :) If there's a problem with PaperClips we'll figure out what it is and fix it.
That's very odd that you're seeing such poor performance, since I routinely print 50-60 pages with only a one or two second delay. Would you open a bug report in the tracker and attach a snippet I can run to see what you're talking about?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I'm waiting on my sourceforge account to be created. Here's where i'm at. I've removed any formatting I've got and I'm stuck with a basic table that has 9 columns and 4000 rows. That's 36000 cells.
I've used your standalone Snippet7.java file to simulate this using your code:
String text = "The quick brown fox";
for ( int i = 0; i < 36000; i++ )
grid.add( new TextPrint( text ) );
ScalePrint print = new ScalePrint(grid);
PagePrint page = new PagePrint( print );
page.setHeader( new SimplePageDecoration( new TextPrint( "Snippet7.java", SWT.CENTER ) ) );
page.setFooter( new PageNumberPageDecoration( SWT.CENTER ) );
page.setHeaderGap( 5 );
page.setFooterGap( 5 );
return page;
}
This becomes very slow. While it may not seem to be very practical to print 150 pages worth of data (I agree), it is still feasable that a click will hit the preview button anyway. Therefore, we cannot have the application hanging with large sets.
I'll put in a bug report when I get my account.
Cheers,
-Marco
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Okay, here's a preliminary result. I've written a small benchmarking framework and am benchmarking Snippets 2 through 7. 100 runs each, with an average run time of 73.4ms. Commenting out line 181 of PaperClips.java: "gc.setAdvanced(true);" yields a 75% improvement in speed: 18.9ms average. Wow.
The reason I'm turning on advanced mode is that in the preview the font sizes tend to jump around, and right-aligned text tends to not line up. This can also occur in a RotatePrint or ScalePrint since the layout is calculated in normal mode but then rendered in advanced mode, which doesn't always look the same (especially on Windows). To get around this I was simply setting advanced mode once at the beginning of any layout or printing operation and it took care of the misaligned layouts.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I've made PaperClips.getPageEnumeration() public API (turns out it was already written) and am now using that instead of PaperClips.getPages() in PrintPreview. I also added setLazyPageLayout(boolean), getRunningPageCount(), and isLayoutComplete() as new methods on PrintPreview. Lastly I wrote Snippet8 (just a copy of Snippet7 but tweaked to be a huge document and to use the lazy APIs). I will release the code to HEAD in the morning, but in the meantime here's some tasty benchmarks for you to munch on:
Starting benchmark "getPageEnumeration":
Run 1/10: 2015ms
Run 2/10: 1782ms
Run 3/10: 1765ms
Run 4/10: 1766ms
Run 5/10: 1766ms
Run 6/10: 1765ms
Run 7/10: 1766ms
Run 8/10: 1797ms
Run 9/10: 1765ms
Run 10/10: 1766ms
Total: 17953ms
Average: 1,795.3ms
Starting benchmark "getPages":
Run 1/10: 13406ms
Run 2/10: 13359ms
Run 3/10: 13344ms
Run 4/10: 13203ms
Run 5/10: 13281ms
Run 6/10: 13282ms
Run 7/10: 13312ms
Run 8/10: 13156ms
Run 9/10: 13141ms
Run 10/10: 13375ms
Total: 132859ms
Average: 13,285.9ms
The GridPrint in Snippet8 has 50000 "quick brown fox" TextPrints. As you can see the improvement is dramatic, with about an 86% increase in speed.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I've released my latest changes to SVN, revision 360. See PrintPreview.setLazyPageLoading(boolean). Also see Snippet8 which is just a copy of Snippet7, except the document is huge and the print preview is using lazy loading.
Does this address your problem?
Matthew
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Firsthand, awesome work. There is a noticable difference in the loading times. There is still however a delay given very large sets, but I may have a solution proposal for you. How about when the Print Preview dialog is opened, instead of locking the system, we simply use a Job thread to create the Print and render it, meanwhile, we post a message on the screen to the effect of "Generating your preview"? When the render is ready, we display it?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The background thread is a good idea. However I won't hardcode English text into PrintPreview to avoid internationalization issues. I think that showing a busy cursor until the layout is ready.
Unfortunately I'm typing this on my phone as my windows pc won't boot :-S
Matthew
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I won't be implementing a Job interface, as this would introduce a new dependency outside of SWT.
I also can't layout pages in a separate thread because on some platforms (Linux GTK for one) all printer access must happen in the display thread. I don't like it but I have to code for the lowest common denominator.
The solution as I see it is to introduce an incremental layout using Display.timerExec with a low timer value, with each timer tick laying out a single page until the entire document is done. The display would remain responsive, although maybe a little sluggish.
It may be important to be able to listen to the page count as it increments so the application can update labels (i.e. "Page 3 of 10"). I'd prefer not to introduce a new listener interface to accommodate this. Ideally if there is an existing SWT event type we could reuse that.
This discussion should really be in the bug tracker. Would you mind filling out a feature request?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hallo,
I combined Snippet7 and Snippet4 for a preview of a scaled grid.
When I have tables with 20 columns and 620 rows the preview works only for the first 3 pages. The preview hangs by page 4.
On the otherside I can print the hole document.
I get the same problem, when I use BigPrint instead of ScalePrint.
I don't have this preview-problem with smaller tables.
I'am using Eclispe Version: 3.2.0 Build-ID: M20070212-1330
Tristan
The huge number of TextPrints is causing you to run out of operating system graphics resources. i.e. with 20 columns and 620 rows, and a font and foreground color allocated for each cell, you are allocating 24800 resources just for that document.
I have implemented a resource pool that shares Font and Color instances on a per device basis. Please check out the latest sources from SVN, run your snippet again, and let me know if that fixes your problem.
Matthew
Hallo Matthew,
thank you very much. The latest sources from SVN works with my huge tables.
And I like the new Snippet7-Example.
Tristan
Glad that helped. I'll be releasing version 1.0.2 in the next few days.
I'm having the same issue, but with much larger table. I've got about 8 or 9 columns with about 3500 rows. Print preview takes a long time to load (minutes). I have the latest source. Is there any way to speed it up?
The problem is that PrintPreview wants to lay out the entire document before displaying pages. This is so that PageNumberPrints can display the correct total page count, which is not known until you lay out all pages.
An approach I've been considering was to use an iterator for getting pages in a print job, rather than the current approach which gets an array. Pages would only be generated as needed. However this requires that you use a different page number format which would not show the total page count (since it's inaccurate).
To prevent breaking backward compatibility, we would have to add a property (probably to PrintJob) which indicates that the document should do layout one page at a time.
Hi Matt,
I was actually thinking the same thing. Would there be any other means of determining the number of total pages without doing a full render? I'm currently previewing small lists (< 100 rows), and they aren't fast (no offence). This is simply 3 pages worth of data. When we get to the 300-400 row range, we notice a lot of latency.
I don't want to sound like I'm slandering your work, because so far I think it's great...and I appreciate your efforts.
Facts don't offend me. :) If there's a problem with PaperClips we'll figure out what it is and fix it.
That's very odd that you're seeing such poor performance, since I routinely print 50-60 pages with only a one or two second delay. Would you open a bug report in the tracker and attach a snippet I can run to see what you're talking about?
I just had a thought: where is your data coming from? Is there any latency when retrieving your data, e.g. from a database?
Hi Matt,
I'm pulling my data from a populated RCP table, so there shouldn't be any issues there. I'll open a bug with a snippet so you can have a look.
I'm going to try your example snippets first before putting you through the trouble. I'll get back to you shortly.
Hi Matt,
I'm waiting on my sourceforge account to be created. Here's where i'm at. I've removed any formatting I've got and I'm stuck with a basic table that has 9 columns and 4000 rows. That's 36000 cells.
I've used your standalone Snippet7.java file to simulate this using your code:
private Print createPrint() {
DefaultGridLook look = new DefaultGridLook();
look.setCellSpacing( 5, 2 );
GridPrint grid = new GridPrint( "p:g, p:g, p:g, p:g, p:g, p:g, p:g, p:g, p:g", look );
String text = "The quick brown fox";
for ( int i = 0; i < 36000; i++ )
grid.add( new TextPrint( text ) );
ScalePrint print = new ScalePrint(grid);
PagePrint page = new PagePrint( print );
page.setHeader( new SimplePageDecoration( new TextPrint( "Snippet7.java", SWT.CENTER ) ) );
page.setFooter( new PageNumberPageDecoration( SWT.CENTER ) );
page.setHeaderGap( 5 );
page.setFooterGap( 5 );
return page;
}
This becomes very slow. While it may not seem to be very practical to print 150 pages worth of data (I agree), it is still feasable that a click will hit the preview button anyway. Therefore, we cannot have the application hanging with large sets.
I'll put in a bug report when I get my account.
Cheers,
-Marco
Okay, here's a preliminary result. I've written a small benchmarking framework and am benchmarking Snippets 2 through 7. 100 runs each, with an average run time of 73.4ms. Commenting out line 181 of PaperClips.java: "gc.setAdvanced(true);" yields a 75% improvement in speed: 18.9ms average. Wow.
The reason I'm turning on advanced mode is that in the preview the font sizes tend to jump around, and right-aligned text tends to not line up. This can also occur in a RotatePrint or ScalePrint since the layout is calculated in normal mode but then rendered in advanced mode, which doesn't always look the same (especially on Windows). To get around this I was simply setting advanced mode once at the beginning of any layout or printing operation and it took care of the misaligned layouts.
I've made PaperClips.getPageEnumeration() public API (turns out it was already written) and am now using that instead of PaperClips.getPages() in PrintPreview. I also added setLazyPageLayout(boolean), getRunningPageCount(), and isLayoutComplete() as new methods on PrintPreview. Lastly I wrote Snippet8 (just a copy of Snippet7 but tweaked to be a huge document and to use the lazy APIs). I will release the code to HEAD in the morning, but in the meantime here's some tasty benchmarks for you to munch on:
Starting benchmark "getPageEnumeration":
Run 1/10: 2015ms
Run 2/10: 1782ms
Run 3/10: 1765ms
Run 4/10: 1766ms
Run 5/10: 1766ms
Run 6/10: 1765ms
Run 7/10: 1766ms
Run 8/10: 1797ms
Run 9/10: 1765ms
Run 10/10: 1766ms
Total: 17953ms
Average: 1,795.3ms
Starting benchmark "getPages":
Run 1/10: 13406ms
Run 2/10: 13359ms
Run 3/10: 13344ms
Run 4/10: 13203ms
Run 5/10: 13281ms
Run 6/10: 13282ms
Run 7/10: 13312ms
Run 8/10: 13156ms
Run 9/10: 13141ms
Run 10/10: 13375ms
Total: 132859ms
Average: 13,285.9ms
The GridPrint in Snippet8 has 50000 "quick brown fox" TextPrints. As you can see the improvement is dramatic, with about an 86% increase in speed.
Marco,
I've released my latest changes to SVN, revision 360. See PrintPreview.setLazyPageLoading(boolean). Also see Snippet8 which is just a copy of Snippet7, except the document is huge and the print preview is using lazy loading.
Does this address your problem?
Matthew
Hi Matthew,
I'm going to download it today and take it for a rip. I'll let you know. Thanks a lot for your hard work!
Hi Matt,
Firsthand, awesome work. There is a noticable difference in the loading times. There is still however a delay given very large sets, but I may have a solution proposal for you. How about when the Print Preview dialog is opened, instead of locking the system, we simply use a Job thread to create the Print and render it, meanwhile, we post a message on the screen to the effect of "Generating your preview"? When the render is ready, we display it?
The background thread is a good idea. However I won't hardcode English text into PrintPreview to avoid internationalization issues. I think that showing a busy cursor until the layout is ready.
Unfortunately I'm typing this on my phone as my windows pc won't boot :-S
Matthew
Hi Matt,
Did you ever get around to implementing the Job thread for Print Preview?
I won't be implementing a Job interface, as this would introduce a new dependency outside of SWT.
I also can't layout pages in a separate thread because on some platforms (Linux GTK for one) all printer access must happen in the display thread. I don't like it but I have to code for the lowest common denominator.
The solution as I see it is to introduce an incremental layout using Display.timerExec with a low timer value, with each timer tick laying out a single page until the entire document is done. The display would remain responsive, although maybe a little sluggish.
It may be important to be able to listen to the page count as it increments so the application can update labels (i.e. "Page 3 of 10"). I'd prefer not to introduce a new listener interface to accommodate this. Ideally if there is an existing SWT event type we could reuse that.
This discussion should really be in the bug tracker. Would you mind filling out a feature request?
Feature request created. Thanks Matt.