Well, sort of. I implemented some changes that made a lot of difference. I also discussed these chanegs with MS and they approved of them.
Below is the sumamry from MS support technician. It probably does not contain everything you need, but hopefully something to get you started. Creation/caching of fonts was the main issue in my case. Took very long time and the font cache was emptied all the time.
---------------------------------------------
Hi Jonas,
In accordance with my previous email and based on your feedback this case will be closed.
If you have comments or questions, you can reactivate the case or create a new one.
Thanks for collaboration!
Best regards,
Alexander Kats
[SOAP]
Subjective
==========
PROBLEM DESCRIPTION
===================
Creation of pdf invoices are taking around 5-6 seconds. Some of the reports have been converted from AX 3.0 to AX 2009 and the customer is really seeing this performance problem and is really annoyed.
First of all thanks for the results of your investigation related to the font caching and the fact related to when the writePDFFontSpecs method loads the unicodeToIndex map, the process is taking a long time.
After some research, I could see that a problem related to performance in pdf reports realted to Arial Unicode was logged with development team and the information that came back was that even though the fix may bring performance improvement it can affect the execution time for the simple reports for the existing customers and is proving to be a high risk, high cost fix. Taking that into consideration, the recommended workaround for this issue would be to use a batch processing system that will print reports to PDF and send them via email, and using batch jobs to print those reports.
I am not sure whether you and your customer would be able to go for this option of printing reports using batch process. If so I would like to ask you to check this and get back to us. Also there has been another related performance problem raised but we were not able to reproduce that in standard AX . So please let us know if you could go ahead with this option of using batch process . If not I would like to ask you to send us all the details related to a specific report and the time taken and we will see if major performance problem exists there. Still I would like to make you aware that since the X++ Reporting would be removed in AX 6.0, we could go ahead with an escalation if we have a clear repro showing the exact details and impact.
By the time you get back with updates another engineer will take ownership and work with you to see for any other options.
Objective
=========
NOT REQUIRED
Assessment
==========
SUMMARY of TROUBLESHOOTING
==========================
1) Result of first communication via phone:
I would like to provide summary of phone call + current status:
- As I stated before I could repeat the issue with PDF performance, I mean the time PDF creation takes more time than the repro with font or more than word file creation. We analyzed the issue with experts and would like to share that there was a similar issue once before - in that case the issue only existed on the customer's production server, in dev. was fast and when it was tested on MS server it was also fast, but on customer production server it was slow. At the end customer agreed to use third party PDF generator which provides more features and is faster (and is free). Actually I haven’t found the same issue in internal database from customer, expect that I have meant above.
From escalation to Development team perspective it is really important to have a good consistent repro, by having it development can start investigation – it means that case can be escalated as request for hotfix based on the performance difference between AX3 and AX2009 if it has degraded. Also in order to escalate the issue I would like to understand how customer’s business has been impacting by such performance – in other words I would like to have information about customer environment like OS version, Ax Version and log file by Ax tracing - to trace it please use from the Ax server configuration utility, Tracing tabpage with all enabled feature like RPC calls, X++ and function and then it can be analyzed by AX Trace parser (I have shown you how it works).If we have no useful information in this log, I will provide another tool which collects log with more details, however this tool is very hard in using.
2) Result of collaboration with Tech lead and my own investigation:
I had been collaboration with our experts’ team and would like to share with you result of investigation; here it is a trace with the AX Event Tracer. Outcome was the following:
Most of the time is spent on creating the font. There are 4 different fonts on the report you sent me. Most time is spent in getting font information via WinAPI or kernel methods.
The developer was aware of this fact and added a font caching (see PDFViewer\addFont and class SysPDFFontCache).
But the font cache is always deleted after a report is printed. This has something to do with the PrintJobSettings being shared otherwise.
The deletion is done on the method Info\onEventGoingIdle.
There is four found possibilities to work-around this problem:
2.1) Stop the deletion of the font cache and do it only when the client is closed. So the font would have to be created only once per session, not once for every report.
Actually it is known how much of a problem the mentioned PrintJobSettings issue is, should be investigated further.
2.2) Store the font information in a table, so it has not to be generated every time.
This is not that easy but possible and needs some programming efforts.
(That’s something which will be the best approach from X++ point of view and need more investigation)
2.3) Use one of the predefined PDF Postscript fonts. You will find the names of that here \Classes\PDFViewer\predefinedFontFactory
For example the Helvetica Font is similar to the Arial font. This would be by far the best solution as the performance would increase and the size would decrease as this font does not need to be embedded (those fonts are part of each PDF Reader).
The only problem is that those fonts are not free and you need to buy them. (And I don’t know how to install Postscript font on Windows)
2.4) Use and PDFPrinter software which emulates a printer device.
Two freeware products are: PDFCreator and PrimoPDF
3)Partner answered with the following info:
"I have changed one method. I took a guess that I could add the printer device name in the key so that different printers will have their own cache...
SysPDFFontType2 getOrCreateFont(str _fontName, PrintJobSettings _printJobSettings)
{
SysPDFFontType2 font;
;
if (name2PDFFont.exists(_fontName + _printJobSettings.deviceName()))
{
font = name2PDFFont.lookup(_fontName + _printJobSettings.deviceName());
}
else
{
font = new SysPDFFontType2(_fontName, _printJobSettings);
name2PDFFont.insert(_fontName + _printJobSettings.deviceName(), font);
}
return font;
}
... added a method. This method returns the cached CMap for a font/printer combination, since that also took long time
Map getCMap(str _fontName, PrintJobSettings _printJobSettings)
{
SysPDFFontType2 font;
Map cMap;
;
if (pdfFont2CMap.exists(_fontName + _printJobSettings.deviceName()))
{
cMap = pdfFont2CMap.lookup(_fontName + _printJobSettings.deviceName());
}
else
{
font = this.getOrCreateFont(_fontName, _printJobSettings);
cMap = font.getCMap(_printJobSettings.hdc());
pdfFont2CMap.insert(_fontName + _printJobSettings.deviceName(), cMap);
}
return cMap;
}
In the PDFViewer class I changed the writePDFFontSpecs method to get the cMap from the cache instead
//unicodeToIndex = fontType2Descriptor.getCMap(printJobSettings.hDC());
unicodeToIndex = sspdffontcache.getCMap(fontType2Descriptor.fontName(), printJobSettings);
These changes have not caused any problems (yet), but actually I do feel a bit unsecure about them.
The PDFViewer class is still slow, but I think that it would be possible to optimize it a lot more with the right knowledge.
ANSWER from SUPPORT:
Your answer was reviewed by Development and it looks good however it cannot be released through official hotfix but can be treat as suggestion how to improve as part of project modification and can be published on blogs or available by request. Also there is some improvements which are done by support team as part of working on support cases.
As result of investigation for this case + investigation for previous cases from partner's community we can compile as one united set which can be available by request from partner.
5) Last comments from partner side:
The variable filename “bmpImage” is used to store a copy to a bitmap file. This file is never cleaned up afterwards. The cleanup was added but encountered a problem, since the file was locked for some strange reason.
Thus, the last lines of writeBitmap method look like this:
this.appendTextToPage(s);
// Get rid of the temporary files. I had to move this code to be able to release the file handle,
// since the img object for some strange reason keeps a lock on the bmpImage file /Jonas
img = null;
WinAPI::deleteFile(fn);
WinAPI::deleteFile(bmpImage);
ROOT CAUSE (if known)
=====================
Finally we agreed that partner's code improvements can be reviewed by MS and expectation is to receive some comments if it is fine from development perspective or not. Answer was given that it is fine and as addition some more code suggestions were provided by MS support team.
As result partner has changes which impacts performance and it works faster than it was.