<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Performance Optimization of Arrays - Part I</title><link>http://blogs.msdn.com/jscript/archive/2008/03/25/performance-optimization-of-arrays-part-i.aspx</link><description>Hello Friends, Have you observed better performance of Array operations in IE8 than IE7? If not, try the following code in both IE7 &amp;amp; IE8 and I can bet you would not leave this page without reading till the last word. var arrObj = new Array(); var</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>re: Performance Optimization of Arrays - Part I</title><link>http://blogs.msdn.com/jscript/archive/2008/03/25/performance-optimization-of-arrays-part-i.aspx#8337324</link><pubDate>Wed, 26 Mar 2008 09:51:16 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8337324</guid><dc:creator>Sebastian Werner</dc:creator><description>&lt;p&gt;That's really interesting. We already thought that you have implemented it this way in the old engine.&lt;/p&gt;
&lt;p&gt;Would be great if IE8 would also allow to extending (inheriting) from arrays using the normal prototype chain:&lt;/p&gt;
&lt;p&gt;function QxArray() {&lt;/p&gt;
&lt;p&gt; &amp;nbsp;Array.prototype.call(this);&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;QxArray.prototype = new Array;&lt;/p&gt;
&lt;p&gt;This still seems not to be possible. This works in all other browsers. Please have a look at this as well.&lt;/p&gt;
</description></item><item><title>re: Performance Optimization of Arrays - Part I</title><link>http://blogs.msdn.com/jscript/archive/2008/03/25/performance-optimization-of-arrays-part-i.aspx#8337650</link><pubDate>Wed, 26 Mar 2008 15:31:08 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8337650</guid><dc:creator>Dave</dc:creator><description>&lt;p&gt;Great work! This will definitely improve performance. Like Sebastian, I would like to see it be possible to extend Array. Right now, that seems to break because of issues with the .length property.&lt;/p&gt;
</description></item><item><title>re: Performance Optimization of Arrays - Part I</title><link>http://blogs.msdn.com/jscript/archive/2008/03/25/performance-optimization-of-arrays-part-i.aspx#8337697</link><pubDate>Wed, 26 Mar 2008 16:23:05 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8337697</guid><dc:creator>Hold your Horses</dc:creator><description>&lt;p&gt;Woah! that was definately messed up!&lt;/p&gt;
&lt;p&gt;But as Sebastian questions...&lt;/p&gt;
&lt;p&gt;Can I prototype on the JavaScript Array Object or not? &amp;nbsp;If not, GO BACK TO THE DRAWING BOARD!&lt;/p&gt;
&lt;p&gt;Otherwise, thanks for the performance improvement, it is much appreciated.&lt;/p&gt;
</description></item><item><title>re: Performance Optimization of Arrays - Part I</title><link>http://blogs.msdn.com/jscript/archive/2008/03/25/performance-optimization-of-arrays-part-i.aspx#8338237</link><pubDate>Wed, 26 Mar 2008 21:53:12 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8338237</guid><dc:creator>TNO</dc:creator><description>&lt;p&gt;Out of curiosity, why didn't you use the array literal? []&lt;/p&gt;
</description></item><item><title>re: Performance Optimization of Arrays - Part I</title><link>http://blogs.msdn.com/jscript/archive/2008/03/25/performance-optimization-of-arrays-part-i.aspx#8341664</link><pubDate>Fri, 28 Mar 2008 16:27:11 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8341664</guid><dc:creator>Jaiprakash</dc:creator><description>&lt;p&gt;Sebastian, Dave - Thanks for pointing out the issue with inheriting from Array.prototype scenarios. &lt;/p&gt;
&lt;p&gt;TNO - There is no specific reason for not using array literals, I just started with new Array() and continued with it for consistency. The fix works for all array objects, no matter how they are declared in code.&lt;/p&gt;
&lt;p&gt;- JP&lt;/p&gt;
</description></item><item><title>ECMAScript doesn't make an array dense just because you specify a length in the Array constructor</title><link>http://blogs.msdn.com/jscript/archive/2008/03/25/performance-optimization-of-arrays-part-i.aspx#8369217</link><pubDate>Tue, 08 Apr 2008 18:08:57 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8369217</guid><dc:creator>liorean</dc:creator><description>&lt;p&gt;Is this safe though? For something like &amp;quot;var a=new Array(0xffffffff),a[0xfffffffe]=0xfffffffe;&amp;quot; I really hope you're not allocating a true array of 2^32 elements.&lt;/p&gt;
&lt;p&gt;Oh, and not really on topic but still related, you have a set of bugs in those functions that extend the array in IE8b1 and earlier. I'll show you the case of Array.prototype.push, but you have analogous bugs in the other array functions:&lt;/p&gt;
&lt;p&gt;----&amp;lt;example&amp;gt;----&lt;/p&gt;
&lt;p&gt;var&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;a=[0,1,2,3],&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;b=[],&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;i=0xfffffffd;&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;a[i]=i++;&lt;/p&gt;
&lt;p&gt;try{&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;alert('Initial length: '+a.length);&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;alert('a.push returns: '+a.push(i++,i++,i++));&lt;/p&gt;
&lt;p&gt;}catch(err){&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;alert('ERROR:\n\n Name: '+err.name+'\n\n Description: '+err.description+'\n\n Message: '+err.message+'\n\n Number: '+err.number);&lt;/p&gt;
&lt;p&gt;}finally{&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;for(i in a)&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;b.push(i+': '+a[i]);&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;b.push('length: '+a.length);&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;alert(b.join('\n'));&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;----&amp;lt;/example&amp;gt;----&lt;/p&gt;
&lt;p&gt;----&amp;lt;IE8b1 results&amp;gt;----&lt;/p&gt;
&lt;p&gt;- &amp;quot;Initial length:4294967294&amp;quot;&lt;/p&gt;
&lt;p&gt;- &amp;quot;a.push returns: 1&amp;quot;&lt;/p&gt;
&lt;p&gt;- No RangeError!&lt;/p&gt;
&lt;p&gt;- Array members listed in the finally clause:&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;0: 4294967296&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;-2: 4294967294&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;-1: 4294967295&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;length: 1&lt;/p&gt;
&lt;p&gt;----&amp;lt;/IE8b1 results&amp;gt;----&lt;/p&gt;
&lt;p&gt;----&amp;lt;Correct results&amp;gt;----&lt;/p&gt;
&lt;p&gt;- &amp;quot;Initial length: 4294967294&amp;quot;&lt;/p&gt;
&lt;p&gt;- RangeError&lt;/p&gt;
&lt;p&gt;- a.push doesn't return, it throws a RangeError&lt;/p&gt;
&lt;p&gt;- Array members listed in the finally clause:&lt;/p&gt;
&lt;p&gt;0: 0&lt;/p&gt;
&lt;p&gt;1: 1&lt;/p&gt;
&lt;p&gt;2: 2&lt;/p&gt;
&lt;p&gt;3: 3&lt;/p&gt;
&lt;p&gt;4294967293: 4294967293&lt;/p&gt;
&lt;p&gt;4294967294: 4294967294&lt;/p&gt;
&lt;p&gt;4294967295: 4294967295&lt;/p&gt;
&lt;p&gt;4294967296: 4294967296&lt;/p&gt;
&lt;p&gt;length: 4294967295&lt;/p&gt;
&lt;p&gt;----&amp;lt;/Correct results&amp;gt;----&lt;/p&gt;
&lt;p&gt;Why is that the correct behaviour? Well, the relevant pieces of the ECMAScript spec are &amp;quot;15.4.4.7 Array.prototype.push&amp;quot;, &amp;quot;9.6 ToUint32&amp;quot; and &amp;quot;15.4.5.1 [[Put]]&amp;quot;.&lt;/p&gt;
&lt;p&gt;In step 2 in the algorithm of 15.4.4.7 the variable n is set to the result of calling ToUint32 with the length of the array as argument. This is the only time the length is read out in that algorithm. The type of the variable n is not specified here.&lt;/p&gt;
&lt;p&gt;In step 4 in the algorithm of 9.6 the variable k is specified to be of Number type. The result of ToUint32 is thus a uint32 value stored in a Number (double precision floating point) type and not a uint32 type.&lt;/p&gt;
&lt;p&gt;In step 5 in the algorithm of 15.4.4.7 the variable n is increased by 1. Since n is a Number and not a uint32 type, this means n may contain values of 2^32 or larger.&lt;/p&gt;
&lt;p&gt;In step 4 in the algorithm of 15.4.4.7 a property with the name gotten from ToString(n) is assigned the value of the respective argument.&lt;/p&gt;
&lt;p&gt;In step 7 in the algorithm of 15.4.4.7 [[put]] is called with &amp;quot;length&amp;quot; and the value of n.&lt;/p&gt;
&lt;p&gt;In step 13 in the algorithm of 15.4.5.1 the value to set is compared to the result of calling ToUint32 on that value. If not equal, a RangeError should here be thrown.&lt;/p&gt;
&lt;p&gt;Applied to the example, this is what should happen:&lt;/p&gt;
&lt;p&gt;00. a.length is 4294967294 (2^32-2)&lt;/p&gt;
&lt;p&gt;01. a.push is called&lt;/p&gt;
&lt;p&gt;02. n is set to ToUint32(length)&lt;/p&gt;
&lt;p&gt;03. The property a[n] is set to 4294967294&lt;/p&gt;
&lt;p&gt;04. n is an array index thus a.length is set to n+1 = 4294967295 (2^32-1, which is maximum value for the length)&lt;/p&gt;
&lt;p&gt;05. n is increased to 4294967295&lt;/p&gt;
&lt;p&gt;06. The property a[n] is set to 4294967295&lt;/p&gt;
&lt;p&gt;07. n is increased to 4294967296 (2^32, one larger than maximum length)&lt;/p&gt;
&lt;p&gt;08. The property a[n] is set to 4294967296&lt;/p&gt;
&lt;p&gt;09. n is increased to 4294967297 (2^32+1, two larger than maximum length)&lt;/p&gt;
&lt;p&gt;10. [[put]] is called with &amp;quot;length&amp;quot; and n as arguments.&lt;/p&gt;
&lt;p&gt;11. [[put]] compares 4294967297 to ToUint32(4294967297)=1 and finds they are not equal, and throws a RangeError&lt;/p&gt;
&lt;p&gt;Relevant spec text (ECMA262-3ed):&lt;/p&gt;
&lt;p&gt;----&lt;/p&gt;
&lt;p&gt;15.4.4.7 Array.prototype.push ( [ item1 [ , item2 [ , &amp;amp;#8230; ] ] ] )&lt;/p&gt;
&lt;p&gt;The arguments are appended to the end of the array, in the order in which they appear. The new length of the array is returned as the result of the call.&lt;/p&gt;
&lt;p&gt;When the push method is called with zero or more arguments item1, item2, etc., the following steps are taken:&lt;/p&gt;
&lt;p&gt;1. Call the [[Get]] method of this object with argument &amp;quot;length&amp;quot;.&lt;/p&gt;
&lt;p&gt;2. Let n be the result of calling ToUint32(Result(1)).&lt;/p&gt;
&lt;p&gt;3. Get the next argument in the argument list; if there are no more arguments, go to step 7.&lt;/p&gt;
&lt;p&gt;4. Call the [[Put]] method of this object with arguments ToString(n) and Result(3).&lt;/p&gt;
&lt;p&gt;5. Increase n by 1.&lt;/p&gt;
&lt;p&gt;6. Go to step 3.&lt;/p&gt;
&lt;p&gt;7. Call the [[Put]] method of this object with arguments &amp;quot;length&amp;quot; and n.&lt;/p&gt;
&lt;p&gt;8. Return n.&lt;/p&gt;
&lt;p&gt;The length property of the push method is 1.&lt;/p&gt;
&lt;p&gt;NOTE&lt;/p&gt;
&lt;p&gt;The push function is intentionally generic; it does not require that its this value be an Array object.&lt;/p&gt;
&lt;p&gt;Therefore it can be transferred to other kinds of objects for use as a method. Whether the push function can be applied successfully to a host object is implementation-dependent.&lt;/p&gt;
&lt;p&gt;----&lt;/p&gt;
&lt;p&gt;9.6 ToUint32: (Unsigned 32 Bit Integer)&lt;/p&gt;
&lt;p&gt;The operator ToUint32 converts its argument to one of 2^32 integer values in the range 0 through 2^32&amp;amp;#8722;1, inclusive. This operator functions as follows:&lt;/p&gt;
&lt;p&gt;1. Call ToNumber on the input argument.&lt;/p&gt;
&lt;p&gt;2. If Result(1) is NaN, +0, &amp;amp;#8722;0, +&amp;amp;#8734;, or &amp;amp;#8722;&amp;amp;#8734;, return +0.&lt;/p&gt;
&lt;p&gt;3. Compute sign(Result(1)) * floor(abs(Result(1))).&lt;/p&gt;
&lt;p&gt;4. Compute Result(3) modulo 2^32; that is, a finite integer value k of Number type with positive sign and less than 2^32 in magnitude such the mathematical difference of Result(3) and k is mathematically an integer multiple of 2^32.&lt;/p&gt;
&lt;p&gt;5. Return Result(4).&lt;/p&gt;
&lt;p&gt;NOTE&lt;/p&gt;
&lt;p&gt;Given the above definition of ToUInt32:&lt;/p&gt;
&lt;p&gt;Step 5 is the only difference between ToUint32 and ToInt32.&lt;/p&gt;
&lt;p&gt;The ToUint32 operation is idempotent: if applied to a result that it produced, the second application leaves that value unchanged.&lt;/p&gt;
&lt;p&gt;ToUint32(ToInt32(x)) is equal to ToUint32(x) for all values of x. (It is to preserve this latter property that +&amp;amp;#8734; and &amp;amp;#8722;&amp;amp;#8734; are mapped to +0.)&lt;/p&gt;
&lt;p&gt;ToUint32 maps &amp;amp;#8722;0 to +0.&lt;/p&gt;
&lt;p&gt;----&lt;/p&gt;
&lt;p&gt;15.4.5.1 [[Put]] (P, V)&lt;/p&gt;
&lt;p&gt;Array objects use a variation of the [[Put]] method used for other native ECMAScript objects (8.6.2.2).&lt;/p&gt;
&lt;p&gt;Assume A is an Array object and P is a string.&lt;/p&gt;
&lt;p&gt;When the [[Put]] method of A is called with property P and value V, the following steps are taken:&lt;/p&gt;
&lt;p&gt;1. Call the [[CanPut]] method of A with name P.&lt;/p&gt;
&lt;p&gt;2. If Result(1) is false, return.&lt;/p&gt;
&lt;p&gt;3. If A doesn&amp;amp;#8217;t have a property with name P, go to step 7.&lt;/p&gt;
&lt;p&gt;4. If P is &amp;quot;length&amp;quot;, go to step 12.&lt;/p&gt;
&lt;p&gt;5. Set the value of property P of A to V.&lt;/p&gt;
&lt;p&gt;6. Go to step 8.&lt;/p&gt;
&lt;p&gt;7. Create a property with name P, set its value to V and give it empty attributes.&lt;/p&gt;
&lt;p&gt;8. If P is not an array index, return.&lt;/p&gt;
&lt;p&gt;9. If ToUint32(P) is less than the value of the length property of A, then return.&lt;/p&gt;
&lt;p&gt;10. Change (or set) the value of the length property of A to ToUint32(P)+1.&lt;/p&gt;
&lt;p&gt;11. Return.&lt;/p&gt;
&lt;p&gt;12. Compute ToUint32(V).&lt;/p&gt;
&lt;p&gt;13. If Result(12) is not equal to ToNumber(V), throw a RangeError exception.&lt;/p&gt;
&lt;p&gt;14. For every integer k that is less than the value of the length property of A but not less than Result(12), if A itself has a property (not an inherited property) named ToString(k), then delete that property.&lt;/p&gt;
&lt;p&gt;15. Set the value of property P of A to Result(12).&lt;/p&gt;
&lt;p&gt;16. Return.&lt;/p&gt;
</description></item><item><title>Performance Optimization of Arrays - Part II</title><link>http://blogs.msdn.com/jscript/archive/2008/03/25/performance-optimization-of-arrays-part-i.aspx#8371166</link><pubDate>Wed, 09 Apr 2008 08:20:12 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8371166</guid><dc:creator>JScript Blog</dc:creator><description>&lt;p&gt;Hello Friends, Hope you have read part I of this topic which I posted few days ago. If not then I would&lt;/p&gt;
</description></item><item><title>re: Performance Optimization of Arrays - Part I</title><link>http://blogs.msdn.com/jscript/archive/2008/03/25/performance-optimization-of-arrays-part-i.aspx#8371198</link><pubDate>Wed, 09 Apr 2008 08:31:32 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8371198</guid><dc:creator>Jaiprakash</dc:creator><description>&lt;FONT face=Verdana,Tahoma color=#4f81bd size=2&gt;
&lt;P&gt;@liorean - No we don’t allocate memory for elements upfront. It is allocated only when indexes are actually populated.&lt;/P&gt;
&lt;P&gt;And many thanks for reporting the bug and writing such a detailed explanation.&lt;/P&gt;
&lt;P&gt;-JP&lt;/P&gt;&lt;/FONT&gt;</description></item><item><title>Interesting Finds: 2008.04.24</title><link>http://blogs.msdn.com/jscript/archive/2008/03/25/performance-optimization-of-arrays-part-i.aspx#8420511</link><pubDate>Thu, 24 Apr 2008 05:44:08 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8420511</guid><dc:creator>gOODiDEA.NET</dc:creator><description>&lt;p&gt;.NET Video: Write Your First Silverlight Game Increasing the Size of your Stack Web CSS 真的可以浮动么？ xUnit&lt;/p&gt;
</description></item><item><title>Interesting Finds: 2008.04.24</title><link>http://blogs.msdn.com/jscript/archive/2008/03/25/performance-optimization-of-arrays-part-i.aspx#8420517</link><pubDate>Thu, 24 Apr 2008 05:45:29 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8420517</guid><dc:creator>gOODiDEA</dc:creator><description>&lt;p&gt;.NETVideo:WriteYourFirstSilverlightGameIncreasingtheSizeofyourStackWebCSS真的可以浮动么...&lt;/p&gt;
</description></item><item><title>re: Performance Optimization of Arrays - Part I</title><link>http://blogs.msdn.com/jscript/archive/2008/03/25/performance-optimization-of-arrays-part-i.aspx#8571507</link><pubDate>Tue, 03 Jun 2008 16:34:14 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8571507</guid><dc:creator>Darryl</dc:creator><description>&lt;p&gt;I'm using JScript 5.7.5730 as a server-side language in a classic-ASP-like environment, and I'm a little confused. &amp;nbsp;&lt;/p&gt;
&lt;p&gt;You talk about arrays &amp;quot;now&amp;quot; and arrays &amp;quot;before&amp;quot;, and the difference appears to be based on IE7/8. &amp;nbsp;But what are the real version numbers? &amp;nbsp;&lt;/p&gt;
&lt;p&gt;Do I in 5.7.5730 have the new array handling?&lt;/p&gt;
&lt;p&gt;Thanks,&lt;/p&gt;
&lt;p&gt;Darryl.&lt;/p&gt;
</description></item><item><title>re: Performance Optimization of Arrays - Part I</title><link>http://blogs.msdn.com/jscript/archive/2008/03/25/performance-optimization-of-arrays-part-i.aspx#8571576</link><pubDate>Tue, 03 Jun 2008 17:30:55 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8571576</guid><dc:creator>JSBlog</dc:creator><description>&lt;p&gt;Sorry if I was not clear. As of today, the only way to get these fixes on your box is to install IE8 Beta1 from &lt;a rel="nofollow" target="_new" href="http://www.microsoft.com/windows/products/winfamily/ie/ie8/readiness/Install.htm"&gt;http://www.microsoft.com/windows/products/winfamily/ie/ie8/readiness/Install.htm&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The 5.7.0.5730 is I think IE7, and will not have these fixes.&lt;/p&gt;
&lt;p&gt;- JP [MSFT]&lt;/p&gt;
</description></item><item><title>re: Performance Optimization of Arrays - Part I</title><link>http://blogs.msdn.com/jscript/archive/2008/03/25/performance-optimization-of-arrays-part-i.aspx#9930818</link><pubDate>Tue, 01 Dec 2009 15:51:53 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9930818</guid><dc:creator>Dan Breslau</dc:creator><description>&lt;p&gt;Sorry for coming in late; I know that by now your team is working on finishing up IE9.&lt;/p&gt;
&lt;p&gt;I've been looking into array performance, and I found something that I think is interesting: Passing the array's size into the array constructor does improve the performance for indexed entries in the array (as you described). But it doesn't help when looking up undefined values -- that is, elements that aren't currently indexed in the array. In fact, compared to arrays where the size *isn't* passed into the constructor, it seems there's even a *penalty* for looking up undefined values. Of course, I don't know how this is implemented, but that penalty isn't what I'd expect; is it a bug?&lt;/p&gt;
&lt;p&gt;For details, see &lt;a rel="nofollow" target="_new" href="http://www.outofwhatbox.com/blog/2009/12/javascript-array-performance-and-why-it-matters/"&gt;http://www.outofwhatbox.com/blog/2009/12/javascript-array-performance-and-why-it-matters/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I'd be glad to send you the raw data if it would be helpful.&lt;/p&gt;
</description></item></channel></rss>