locked
WCF slow on Windows 7 under certain weird conditions RRS feed

  • Question

  • I was debugging some slow WCF code and eventually came to the following unexpected result. Here are the steps.

    1. Create an IIS-hosted WCF service, RUNNING ON SERVER 2008 R2 (IMPORTANT!), with one method returning a byte array, as follows: 

    Public Function GetByteArray() As Byte() Implements ITestService.GetByteArray
    	Dim bt(524287) As Byte	'512 KB byte array
    	Dim r As New System.Random()
     
    	For i As Integer = 0 To bt.Length - 1
    		bt(i) = r.Next(256)	'populate the array with random data
    	Next
     
    	Return bt
    End Function
    

     2. Create a WinForms WCF client that calls this method in a loop, let's say, 4 times. Mark the time it takes for every call to execute and display it in a text box (set the Multiline property of your textbox to true!), like this:

    Private Sub Button1_Click(sender As System.Object, e As System.EventArgsHandles Button1.Click
    	Me.TextBox1.Text = ""
     
    	Dim svc As New TestService.TestServiceClient
    	Dim bt() As Byte
    	Dim t As DateTime = Now
     
    	For i As Integer = 1 To 4
    		bt = svc.GetByteArray()
     
    		With Me.TextBox1
    			.Text &= Now.Subtract(t).TotalMilliseconds.ToString("0,000") & vbCrLf
    			.SelectionStart = .Text.Length
    			.ScrollToCaret()
    			.Refresh()
    		End With
     
    		t = Now
    		Application.DoEvents()
    	Next
     
    	MessageBox.Show("done")
    End Sub

    Run the WCF client - the calls should be taking 15 - 30 millisec.

    3. Now update the WCF service to populate the byte array with the same values - replace the line

            bt(i) = r.Next(256)

    with

            bt(i) = 1

    You can actually set bt(i) to any valid byte value (0 - 255), the result will be the same.

    4. Run the client again - you should see the same performance.

    5. Now move your WCF service from Server 2008 to Windows 7, and perform the above two tests gain. When the byte array contains random data, it's still as fast as on Server 2008, but as soon as all bytes are the same, the calls start taking ~3 sec to execute - that's 100 times slower!

    6. Finally, let's make it interesting. Initialise the binary array as follows:

            bt(i) = i Mod 256

    This makes it neihter random nor uniform - it'll now contain repeating sequences of bytes going 0, 1, 2, ... 255, and again 0, 1, 2, ... 255, etc. On Server 2008 - still fast, on Windows 7 - 150 millisec. Faster than uniform, slower than random.

    After I completed these tests, the only thing going in my mind was: WTF!? Can anyone else reproduce? I'm running .Net 4.

     

    Wednesday, October 26, 2011 1:05 AM

Answers

  • Resolved! Turns out I had http compresion enabled on the IIS on Windows 7, but not on Server 2008, and WCF 4 clients now send out the "Accept-encoding: gzip, deflate" header. Furthermore, compression level was set to 9. Turns out compression levels 8 and above cause huge overhead when the data is very uniform. Setting compression level to 7 or below, or turning it off completely, resolves the issue.
    • Marked as answer by Andrew-72 Wednesday, October 26, 2011 6:49 AM
    Wednesday, October 26, 2011 6:49 AM