Standing on the shoulders of giants. RSS 2.0
# Tuesday, August 28, 2007

After reading post about List Predicates at the very informative BCL Team Blog, I did some research to see how flexible the predicates actually are.

I found out that none of the methods taking a Predicate as a parameter support chained delegates (more info about combining delegates), only the delegate added last to the chain is executed in my experience.

Example:

 

// Prepare collection
List<int> list = new List<int>( new int[]{1,2,3,4,5,6} );
        
// function to determine if the int is less than 5
Predicate<int> LT5 = delegate(int x){ return x < 5; };
        
// function to determine if the int is greater than 2
Predicate<int> GT2 = delegate(int x){ return x > 2; };
        
// combine the predicates:
// return true for 2 < x < 5
Predicate<int> GT2LT5 = null;
GT2LT5 += GT2;
GT2LT5 += LT5;
        
List<int> result = list.FindAll(GT2LT5);

// writes 1,2,3,4
result.ForEach( delegate( int x) { Console.WriteLine( x ); });

A work around would be to use the second delegate on the result collection after calling the FindAll method with the first delegate, but this doesn't scale with more delegates.

 

// first use the first delegate
List<int> intermediate = list.FindAll(LT5);
// now use the second delegate on the intermediate result
List<int> result = intermediate.FindAll(GT2);

// writes 3,4
result.ForEach( delegate( int x) {
    Console.WriteLine( x );
});
 

Another solution is to enumerate through the collection and call each delegate in the invocation list.

 

// Prepare collection
List<int> list = new List<int>( new int[]{1,2,3,4,5,6} );

// function to determine if the int is less than 5
Predicate<int> LT5 = delegate(int x){
return x < 5;
};

// function to determine if the int is greater than 2
Predicate<int> GT2 = delegate(int x){
return x > 2;
};
        
// combine the predicates:
// return true for 2 < x < 5
Predicate<int> GT2LT5 = null;
GT2LT5 += GT2;
GT2LT5 += LT5;

// prepare result
List<int> result = new List<int>();

foreach(int i in list ){
    
    bool valid = true;
    
    // GetInvocationList returns all combined delegates
    foreach( Predicate<int> match in GT2LT5.GetInvocationList() ){
        valid = valid & match(i);            
    }

    if( valid ){
        result.Add(i);
    }
}

// writes 3,4
result.ForEach( delegate( int x) {
    Console.WriteLine( x );
});

Both solutions are less than ideal.

Tuesday, August 28, 2007 10:26:33 PM (W. Europe Daylight Time, UTC+02:00)  #    Comments [0] - Trackback
Codesnippet | BCL
# Monday, August 20, 2007

I was supprised with the last results from the XmlWriters and compression stream performance post and figured I did something wrong. So today I re-ran my test and got the results I expected after some data manipulation. The results aren't shocking; writing to a memory stream is about 8% faster when you increase the intialcapacity from 256 bytes to 131072 bytes, further increasing doesn't improve the performance further. Naturally this depends on the data, only 6 xmldocuments I used in this test were greater than 131072 bytes.

Relative performance with increasing initial capacity

 

Methodology:

I saved each xml document to the memorystream 100 times for each initial capacity and removed the 10 best and 10 worst results. The results are relative to the performance of the stream with an initial capacity of 256 bytes.

Notes:

My data is not your data; always do your own testing to determine the 'best' initial capacity for your situation.

Monday, August 20, 2007 10:15:43 PM (W. Europe Daylight Time, UTC+02:00)  #    Comments [0] - Trackback
Development
# Sunday, August 19, 2007

[Update: the results in this post about the performance of a memory stream, when changing the initial capacity are wrong. You can find the correct results in this new post.]

WCF (Windows Communication Framework) introduces additional XmlWriters for more efficient serialization of the messages send between nodes. These writers derive from the abstract XmlDictionaryWriter class and wrap the functionality of existing System.Xml. (For more information visit Justin Smith's post or watch Doug Purdy's COM326 presentation from PDC 05.

I was interested in the performance of the basic UTF-8 text writer and the binary writer for writing content heavy Xml. In this scenario an XmlDictionary won't give much benefit, since in my experience a dictionary will only reduce the size of the tags and not the actual content. More specifically I was interested in the difference in size and the speed of writing of xml files of various sizes.

On to the actual testing: I used the 138 feeds from my blogroll, that do not have a doctype in their feeds, since the XmlDictionaryWriter doesn't support writing those. After loading the feeds in an XmlDataDocument they are saved to the different streams and the size of the streams and the time it takes are written to a log-file for analyzing. Finally the whole process is repeated for a number of initial sizes for the MemoryStream (256 - 524288 in powers of 2).

The results: compression xml files makes them smaller, but it takes longer to write them.

Average performance graph

 As you can see the difference between the text writer the binary writer are small, looking at the averages for all files.

Split for file size chart

When looking at the bytes written / tick you'll see that the binary writer is generally faster for uncompressed files smaller than 8192 bytes and negligible slower for compressed files. Another thing to notice is that the writing speed increases for uncompressed streams as the files get bigger, while it drops a little for compressed streams. The fact that the writing speed drops for the biggest files is probably caused by the mem copy which occures when the memory stream has to increase it's capacity. 

initial capacity chart

 The initial capacity doesn't seems to influence the throughput of the memorystream in a significant way, but this may be related to the data I used to test.

[Download solution for VS 2008]

Notes:

1) According to the MSDN library the compression algorithm the DeflateStream uses is the same the GZipStream uses, so performance should be similar.

2) My data is not your data; you should always do your own testing and decide of the performance and the size are right for you.

Sunday, August 19, 2007 9:55:27 PM (W. Europe Daylight Time, UTC+02:00)  #    Comments [0] - Trackback
C# | XML
# Thursday, August 16, 2007

Yesterday the official build for dasBlog 2.0 was released.

Biggest improvements are the move to .NET 2.0 and the ability to run in Medium trust. For more information about: upgrading, getting help and medium trust, see Scott Hanselman's blog.

Download dasBlog

You can use the BlogML importer to migrate any blogengine, which supports BlogML, to dasBlog.

Thursday, August 16, 2007 3:51:18 PM (W. Europe Daylight Time, UTC+02:00)  #    Comments [0] - Trackback
dasBlog
# Tuesday, August 14, 2007

With the release of dasBlog 2.0 very close, I updated my dasBlog importer for BlogML files. You can now specify the source and destination of the import and export, instead of having to make changes in the sourcecode.

The actual code to import and export the content is not changed since the previous release. Use at your own risk and always make a backup.

[update:] Replaced the zip with a new version using the final dasBlog 2.0 binaries.

DasBlogImporter.zip
Tuesday, August 14, 2007 10:42:29 PM (W. Europe Daylight Time, UTC+02:00)  #    Comments [0] - Trackback
BlogML | dasBlog
# Thursday, August 09, 2007

[via: Coding Horror]

Thursday, August 09, 2007 6:54:25 PM (W. Europe Daylight Time, UTC+02:00)  #    Comments [0] - Trackback
Fun
# Tuesday, July 17, 2007

I posted a new build of the 1.9 branch of das blog to the daily builds location at http://www.paulvanbrenk.com/blog/bits

The following fixes were added by John Forsythe from the 2.0 branch:


  1. Removed Scott's custom "make money from blogging" project from the Solution :)
  2. Added Pauls "#" category fix and updated the assembly version + copyright date (rev 683)
  3. removed the root AjaxDelegate.js and md5.js references from the newtelligence.DasBlog.Web.csproj after they were moved to /scripts subfolder 

 

If you want to make a contribution check out this article by Scott Hanselman, about contributing a patch to dasBlog.

Tuesday, July 17, 2007 1:54:44 PM (W. Europe Daylight Time, UTC+02:00)  #    Comments [0] - Trackback
dasBlog
# Saturday, June 30, 2007

"Always-fresh" releass of dasBlog are available from http://www.paulvanbrenk.com/blog/bits. These builds are made from the subversion head hourly. The current move to .NET 2.0 means the tree is in heavy development, so these may not be the most stable, but are the most recent.

If you want to make a contribution check out this article by Scott Hanselman, about contributing a patch to dasBlog.

Saturday, June 30, 2007 1:28:35 PM (W. Europe Daylight Time, UTC+02:00)  #    Comments [0] - Trackback
dasBlog
About
© Copyright 2008
Paul van Brenk
Sign In
newtelligence dasBlog 2.3.8275.16006
All Content © 2008, Paul van Brenk
DasBlog theme 'Business' created by Christoph De Baene (delarou)