We started with implementing Web Services in VisualWorks. In this
context we found some Issues in XML processing. We saw, that half of the time a WebService call takes is spent in printing the XML.Document onto the HttpPackage. The implementation of SAXCannonicalWriter on each use newly creates 2 Dictionaries textMapping and attributeMapping in #minimalCharacterMap instead of caching them. This takes a lot of time. In XML.Node we have the same behavior in #printCannonical:on:. The character mapping table dictionary is always created as a temporary variable. Furthermore we noted, that other implementations of #printCannonicalOn: use String concatenations in methods that have access to a WriteStream. The initialize method of XML.Element uses a UserMessage "tag := (#undefined << #xml >> 'undefined') asString." as initial value for tag. If you really use internationalization, you get a serious performance bottleneck in xml processing and this makes in my opinion no sense since this is a fixed constant, translating it would break the protocol. I have attached a parcel with the patches we made. These patches reduce the processing time of an WebServices call up to 50%. <?xml version="1.0"?> <st-source> <!-- Name: Sps-Xml-Speed-Patches DbIdentifier: Soops74 DbTrace: 56694 PackageName: Sps-Xml-Speed-Patches Parcel: #('Sps-Xml-Speed-Patches') PrintStringCache: (4,Mac) Date: 1:15:14 pm July 5, 2006 --> <time-stamp>From VisualWorks®, 7.4 of December 5, 2005 on July 5, 2006 at 1:15:14 pm</time-stamp> <do-it>(Dialog confirm: 'You are filing-in a Parcel source file!\\While this is possible it will not have\the same effect as loading the parcel.\None of the Parcel''s prerequisites will\be loaded and none of its load actions\will be performed.\\Are you sure you want to file-in?' withCRs) ifFalse: [self error: 'Parcel file-in abandoned. Choose terminate or close.']</do-it> <shared-variable> <name>MinmalCharacterMap</name> <environment>XML.Node</environment> <private>false</private> <constant>false</constant> <category>caches</category> <attributes> <package>Sps-Xml-Speed-Patches</package> </attributes> </shared-variable> <shared-variable> <name>MinmalAttributeMap</name> <environment>XML.SAXCanonicalWriter</environment> <private>false</private> <constant>false</constant> <category>caches</category> <attributes> <package>Sps-Xml-Speed-Patches</package> </attributes> </shared-variable> <shared-variable> <name>MinimalTextMap</name> <environment>XML.SAXCanonicalWriter</environment> <private>false</private> <constant>false</constant> <category>caches</category> <attributes> <package>Sps-Xml-Speed-Patches</package> </attributes> </shared-variable> <methods> <class-id>XML.Attribute</class-id> <category>printing</category> <body package="Sps-Xml-Speed-Patches" selector="printCanonicalOn:">printCanonicalOn: aStream self tag xmlTagOn: aStream. aStream nextPutAll: '="'. self printCanonical: value on: aStream. aStream nextPut: $"</body> </methods> <methods> <class-id>XML.SAXCanonicalWriter</class-id> <category>initialize</category> <body package="Sps-Xml-Speed-Patches" selector="minimalCharacterMapping">minimalCharacterMapping textMap := self minimalTextMap. attrMap := self minmalAttributeMap</body> <body package="Sps-Xml-Speed-Patches" selector="minimalTextMap">minimalTextMap MinimalTextMap isNil ifTrue: [MinimalTextMap := (Dictionary new: 17) at: $< put: '&lt;'; at: $> put: '&gt;'; at: $" put: '&quot;'; at: $& put: '&amp;'; at: (Character value: 9) put: '&#9;'; at: (Character value: 10) put: '&#10;'; at: (Character value: 13) put: '&#13;'; yourself]. ^MinimalTextMap</body> <body package="Sps-Xml-Speed-Patches" selector="minmalAttributeMap">minmalAttributeMap MinmalAttributeMap isNil ifTrue: [MinmalAttributeMap := (Dictionary new: 17) at: $< put: '&lt;'; at: $> put: '&gt;'; at: $& put: '&amp;'; at: $" put: '&quot;'; at: (Character value: 9) put: '&#9;'; at: (Character value: 10) put: '&#10;'; at: (Character value: 13) put: '&#13;'; yourself]. ^MinmalAttributeMap</body> </methods> <methods> <class-id>XML.Element</class-id> <category>initialize</category> <body package="Sps-Xml-Speed-Patches" selector="initialize">initialize super initialize. tag := 'undefined'. attributes := #()</body> </methods> <methods> <class-id>XML.Element</class-id> <category>printing</category> <body package="Sps-Xml-Speed-Patches" selector="printCanonicalOn:">printCanonicalOn: aStream | az | aStream nextPut: $<. tag xmlTagOn: aStream. attributes == nil ifFalse: [az := attributes size > 1 ifTrue: [attributes asSortedCollection: [:x :y | x key < y key]] ifFalse: [attributes]. az do: [:at | aStream space. at printCanonicalOn: aStream]]. self printNamespacesOn: aStream. elements == nil ifTrue: [aStream nextPutAll: '/>'] ifFalse: [aStream nextPut: $>. elements do: [:e | e printCanonicalOn: aStream]. aStream nextPutAll: '</'. tag xmlTagOn: aStream. aStream nextPut: $>]</body> </methods> <methods> <class-id>XML.Node</class-id> <category>printing</category> <body package="Sps-Xml-Speed-Patches" selector="minimalCharacterMap">minimalCharacterMap MinmalCharacterMap isNil ifTrue: [MinmalCharacterMap := Dictionary new: 17. MinmalCharacterMap at: Character cr put: '&#13;'; at: Character lf put: '&#10;'; at: Character tab put: '&#9;'; at: $& put: '&amp;'; at: $< put: '&lt;'; at: $> put: '&gt;'; at: $" put: '&quot;']. ^MinmalCharacterMap</body> <body package="Sps-Xml-Speed-Patches" selector="printCanonical:on:">printCanonical: text on: aStream "Print myself on the stream in the form described by James Clark's canonical XML." | d | d := self minimalCharacterMap. text do: [:c | | s | (s := d at: c ifAbsent: [nil]) isNil ifTrue: [aStream nextPut: c] ifFalse: [aStream nextPutAll: s]]</body> </methods> <methods> <class-id>Core.CharacterArray</class-id> <category>printing</category> <body package="Sps-Xml-Speed-Patches" selector="xmlTagOn:">xmlTagOn: aStream aStream nextPutAll: self</body> </methods> <methods> <class-id>XML.NodeTag</class-id> <category>printing</category> <body package="Sps-Xml-Speed-Patches" selector="xmlTagOn:">xmlTagOn: aStream qualifier isEmpty ifTrue: [aStream nextPutAll: type] ifFalse: [aStream nextPutAll: qualifier; nextPut: $:; nextPutAll: type]</body> </methods> <do-it>"Imported Classes:"</do-it> <do-it>self error: 'Attempting to file-in parcel imports. Choose terminate or close'</do-it> <class> <name>CharacterArray</name> <environment>Core</environment> <super>Core.ArrayedCollection</super> <private>false</private> <indexed-type>none</indexed-type> <inst-vars></inst-vars> <class-inst-vars></class-inst-vars> <imports></imports> <category>Collections-Text</category> <attributes> <package>Collections-Text</package> </attributes> </class> <class> <name>Node</name> <environment>XML</environment> <super>Core.Object</super> <private>false</private> <indexed-type>none</indexed-type> <inst-vars>parent flags userData </inst-vars> <class-inst-vars></class-inst-vars> <imports></imports> <category>XML-Nodes</category> <attributes> <package>XML</package> </attributes> </class> <class> <name>Element</name> <environment>XML</environment> <super>XML.Node</super> <private>false</private> <indexed-type>none</indexed-type> <inst-vars>tag attributes namespaces elements definition </inst-vars> <class-inst-vars></class-inst-vars> <imports></imports> <category>XML-Nodes</category> <attributes> <package>XML</package> </attributes> </class> <class> <name>Attribute</name> <environment>XML</environment> <super>XML.Node</super> <private>false</private> <indexed-type>none</indexed-type> <inst-vars>name value </inst-vars> <class-inst-vars></class-inst-vars> <imports></imports> <category>XML-Nodes</category> <attributes> <package>XML</package> </attributes> </class> <class> <name>NodeTag</name> <environment>XML</environment> <super>Core.Magnitude</super> <private>false</private> <indexed-type>none</indexed-type> <inst-vars>namespace type qualifier </inst-vars> <class-inst-vars></class-inst-vars> <imports></imports> <category>XML-Parsing</category> <attributes> <package>XML</package> </attributes> </class> <class> <name>SAXCanonicalWriter</name> <environment>XML</environment> <super>XML.SAXWriter</super> <private>false</private> <indexed-type>none</indexed-type> <inst-vars>baseURI </inst-vars> <class-inst-vars></class-inst-vars> <imports></imports> <category>XML-SAX</category> <attributes> <package>XML</package> </attributes> </class> </st-source> Sps-Xml-Speed-Patches.pcl (3K) Download Attachment |
Especially for people, that still use Outlook as email client, I packed
the parcel as a zip archive. Sps-Xml-Speed-Patches.zip (4K) Download Attachment |
Free forum by Nabble | Edit this page |