November, 2010 Archives
Nov
Performance in C# recursion vs. F#
by Mikael Lundin in F#, Programming, Project Euler
I did know that the F# compiler pulls some magic tricks with recursion, but I didn’t know that it could affect performance like I’ve recently discovered. Me and my friend where discussing Project Euler #16, and where he did an iterative C# solution manipulating strings, I went for a recursive list mangling solution in F#.
Project Euler #16
2^15 = 32768 and the sum of its digits is 3 + 2 + 7 + 6 + 8 = 26.
What is the sum of the digits of the number 2^1000?
Iterative string manipulating solution by Whettingstone
public static void Run()
{
/*2^15 = 32768 and the sum of its digits is 3 + 2 + 7 + 6 + 8 = 26.
What is the sum of the digits of the number 2^1000?*/
StringBuilder allDigits = new StringBuilder("1");
int carryOver = 0;
int temp;
for (int i = 0; i < 1000; i++)
{
for (int index = 0; index < allDigits.Length; index++)
{
//Multiply the digit by two
temp = int.Parse(allDigits[index].ToString()) * 2;
if (temp > 9)
{
//The result is 10 or larger so add digit and set carryOver
allDigits.Remove(index, 1);
allDigits.Insert(index, (temp % 10) + carryOver);
carryOver = 1;
}
if (temp <= 9)
{
//The result is less than 10 so add digit and reset carryOver
allDigits.Remove(index, 1);
allDigits.Insert(index, temp + carryOver);
carryOver = 0;
}
if ((index == allDigits.Length - 1) && carryOver == 1)
{
//This is the last index so add the carryOver to the StringBuilder and break the loop
allDigits.Append(carryOver);
carryOver = 0;
break;
}
}
}
//Calculation is done, let's sum it up
int sum = 0;
for (int i = 0; i < allDigits.Length; i++)
{
sum += int.Parse(allDigits[i].ToString());
}
Console.WriteLine("Sum of 2^1000: {0}", sum);
}
This solution is pretty straight forward. Put the result in a string, double all the digits and span out overflowing number to next number in the string. At the end he sums it all up to an int.
Mean execution time: 127 ms
Recursive F# solution by me
let rec calc list exp =
let rec evenOut overhead l =
match (l, overhead) with
| [], 0 -> []
| [], _ -> [overhead]
| head :: tail, _ -> ((overhead + head) % 10) :: (evenOut ((overhead + head) / 10) tail)
match exp with
| 1 -> list
| _ -> calc (list |> List.map (fun x -> x * 2) |> evenOut 0) (exp - 1)
calc [2] 1000 |> List.sum
This is two recursive loops where the outer loop doubles every list item and the inner loop evens out the list with moving any number larger than 9 up the stack.
Mean execution time: 5 ms
Recursive C# translation of the F# version
private List<int> EvenOut(IEnumerable<int> numbers, int overflow)
{
Func<IEnumerable<int>, bool> empty = list =>
{
var enumerator = list.GetEnumerator();
return !enumerator.MoveNext();
};
if (empty(numbers))
{
if (overflow > 0)
return new List<int> { overflow };
return new List<int>();
}
var head = numbers.First();
var n = (overflow + head) % 10;
var newOverflow = (overflow + head) / 10;
var result = EvenOut(numbers.Skip(1), newOverflow);
result.Insert(0, n);
return result;
}
private IEnumerable<int> Calc(IEnumerable<int> numbers, int exp)
{
if (exp == 1)
return numbers;
return Calc(EvenOut(numbers.Select(n => n * 2), 0), exp - 1);
}
[Test]
public void Pe16()
{
Assert.That(this.Calc(new[] { 2 }, 1000).Sum(), Is.EqualTo(1366));
}
In order to explain to my friend whettingstone what I do with my F# code I translated it to C#. I was really suprised when I noticed that it took so much longer to execute.
Mean execution time: 87235 ms
Conclusion
The F# compiler does some heavy optimizations to our recursion and going from F# to C# one must watch out, and not write pure functional constructs without thinking about the consequences. You could problably rewrite the C# recursive solution to be much faster, but an iterative solution is probably the preferred one here.
Nov
ASP.NET RadioButtons in an UL/LI list
by Mikael Lundin in Programming
When you would like to generate a list of radio buttons in ASP.NET you will run into a problem
- RadioButton and Repeater does not play well together
- RadioButtonList have very limited ways to control generated markup
Introducing ULRadioButtonList
This is very inspired by Scott Elikin’s post Render RadioButtonList as an Unordered List UL. I have mostly translated his code to C#.
namespace LiteMedia.Web.UI.WebControls;
{
using System;
using System.Collections;
using System.ComponentModel;
using System.Web.UI;
using System.Web.UI.WebControls;
/// <summary>
/// A control that renderes radio buttons as ul-li list
/// </summary>
/// <remarks>
/// Idea comes from http://scottelkin.com/aspnet/render-radiobuttonlist-as-an-unordered-list-ul/
/// </remarks>
[DefaultProperty("Value"), ToolboxData("<{0}:ULRadioButtonList runat=server />"), Description("Creates a RadioButtonList using an UnorderedList")]
public class ULRadioButtonList : RadioButtonList
{
private const string InputFormat = @"<input id=""{0}"" name=""{1}"" type=""radio"" value=""{2}"" {3} />";
private const string LabelFormat = @"<label for=""{0}"">{1}</label>";
protected override void Render(HtmlTextWriter writer)
{
Func<int, bool> isChecked = index => Items[index].Selected;
Controls.Clear();
using (new Ul(writer, CssClass))
{
var index = 0;
foreach (ListItem item in Items)
{
using (new Li(writer))
{
var clientId = string.Format("{0}_{1}", ClientID, index);
var input = string.Format(InputFormat, clientId, UniqueID, item.Value, isChecked(index) ? "checked" : string.Empty);
var label = string.Format(LabelFormat, clientId, item.Text);
writer.WriteLine(input);
writer.WriteLine(label);
}
}
}
}
public override void DataBind()
{
base.DataBind();
/* Does not seem as .NET manage this in a orderly fashion */
Items.Clear();
foreach (ListItem item in (IEnumerable)DataSource ?? new ListItem[0])
{
Items.Add(item);
}
}
private class Ul : IDisposable
{
private readonly HtmlTextWriter writer;
public Ul(HtmlTextWriter writer, string cssClass)
{
var ul = string.Format("<ul{0}>", string.IsNullOrEmpty(cssClass) ? string.Empty : string.Format(@" class=""{0}""", cssClass));
writer.WriteLine(ul);
writer.Indent++;
this.writer = writer;
}
public void Dispose()
{
writer.Indent--;
writer.WriteLine("</ul>");
}
}
private class Li : IDisposable
{
private readonly HtmlTextWriter writer;
public Li(HtmlTextWriter writer)
{
writer.WriteLine("<li>");
writer.Indent++;
this.writer = writer;
}
public void Dispose()
{
writer.Indent--;
writer.WriteLine("</li>");
}
}
}
}
Usage
<LiteMedia:ULRadioButtonList ID="rblSelectBank" runat="server" CssClass="payment-list" />
Nov
There are too many active security negotiations or secure conversations at the service.
by Mikael Lundin in Programming
I was fighting an error today. It might show itself as
- There are too many active security negotiations or secure conversations at the service.
- The operation has timed out
- SecurityNegotiationException
Conditions for making it happen
- In WCF (Windows Communication Foundation)
- Your clients open and close connections to the server without calling any method
- You protect your service with some kind of security
- You have at least 128 security negotiations in 2 minutes time
Why does it happen?
There is a bug #499859 that WCF does not remove a security session from the list of pending sessions when a client opens and closes a connection without calling any operations. The is room for 128 security session in the pending sessions queue and a security session times out in 2 minutes.
Possible fixes
I’ve come up with the following solutions.
- Best solution would be to make your code stop open/close connections without calling any operations.
Increase the pending sessions queue length
If you can’t fix the problem with open/closing connections you could make the problem less critical by increasing the pending sessions queue length. This you do by creating a custom binding.
<customBinding> <binding name="maxPendingSessionsWsHttpBinding"> <security authenticationMode="SecureConversation"> <localServiceSettings maxPendingSessions="1024" /> </security> <httpTransport /> </binding> </customBinding>
Then you refer to this custom binding from your endpoint like this.
<endpoint address="" binding="customBinding" bindingConfiguration="maxPendingSessionsWsHttpBinding" contract="MyApp.IServiceContract"> </endpoint>
Hope this will help someone along the way. My main inspiration was this forum thread.
Nov
Tips and trix composing HTML emails
by Mikael Lundin in Technicalities
So you need to create an HTML e-mail and you don’t want it to be caught in every spam filter of the web. You also would like if it looked almost the same in different readers. Here’s some stuff I’ve learned.
Reverse PTR Record
If you want people getting your e-mail you should really consider Reverse PTR Record. This is set up by your ISP and will confirm that e-mail that you send actually belongs to the domain it was originated from.
HTML 3.2
What happened in Outlook 2000 was that Microsoft decided to use Word for rendering HTML e-mails. No, I’m not kidding. This is still the case, and that’s why we have to write HTML 3.2 for our e-mails, with table layout and no styles. Don’t end your <BR> tags.
No background images
Background images is a big no-no in most HTML e-mail clients and that is why you should avoid them at any cost. Try to exchange any background images with an <IMG> tag and use background colors to make up for missing image elements.
Use plain text fallback
When sending HTML e-mails you should send both HTML part and plain text. This will make it easier to pass through spam filters and it will give primitive HTML clients some clue of what you’re selling.
Test test test
Some e-mail clients will center your table text by default. Some will not display that image. Others will make everything look like crap. You have to test with different e-mail readers and the cheapest way is to invest in a tool like http://litmus.com/
Nov
NUnit for .NET Framework 4
by Mikael Lundin in Programming
One thing that hits me over and over again is running NUnit or Xunit on libraries built on .NET Framework 4. The fix is very easy but never appears on top results when googling for it.
Fix for getting NUnit and xUnit run tests in DLLs built with .NET Framework 4
Add the following under <configuration> element in nunit-console.exe.config or xunit.console.x86.exe.config if xunit is your drug.
<startup> <requiredRuntime version="v4.0.30319" /> </startup> <runtime> <loadFromRemoteSources enabled="true" /> </runtime>