Long running Close() on SQLDataReader / Slow Close()

by Svelmoe 30. June 2009 13:51

Today I was faced with a problem where the close method on a SQLDataReader took ages – well 10 seconds or so – to complete.

Then I read the following snippet from the documentation:
The Close method fills in the values for output parameters, return values and RecordsAffected, increasing the time that it takes to close a SqlDataReader that was used to process a large or complex query. When the return values and the number of records affected by a query are not significant, the time that it takes to close the SqlDataReader can be reduced by calling the Cancel method of the associated SqlCommand object before calling the Close method.
http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqldatareader.close.aspx

So I tried calling cancel on the command prior to closing the reader and presto – the SQLDataReader closed very fast.

Once again, reading the documentation solved my problem and from this day on, I'll try to cancel the command prior to every close, just to see if it saves some time :)

Using scripts in XSLT

by Svelmoe 2. June 2009 18:36

I mentioned in my last blog post that you can use scripts in XSLT, so I just wanted to show shortly how you can use scripts to show the power it can yield.
Firstly – add a namespace to your XSLT file:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:msxsl="urn:schemas-microsoft-com:xslt"
                xmlns:scripts="urn:scripts.this">

Then you can use the scripts in various situations.
For example, I had to parse some "Yes" and "No" into Boolean strings "true" and "false" (for business logic reasons) so I made a script for that in the bottom of my XSLT file (I made the scripts in C# syntax):

<msxsl:script language="C#" implements-prefix="scripts">
    <![CDATA[
        //return true or false as string instead of "yes" and "no"
    public string getBooleanString(string s0)
    {
      if ((String.Equals(s0, "yes", StringComparison.OrdinalIgnoreCase))
      { return "true"; }
      if (String.Equals(s0, "no", StringComparison.OrdinalIgnoreCase))
      { return "false"; }
      return s0;
    }
    ]]>
</msxsl:script>

Now, I could use this script in my XSLT matching like this:

<xsl:value-of select ="scripts:getBooleanString(./VALUE)"/>

This makes a call to the C# script “getBooleanString” with the value, the script will test it for “Yes” and “No” and return “true” or “false” respectively, or the string itself it it wasn’t one of the two.
Some of the other things I used this for was to compare strings case with case insensitive, and to hold temporary values to avoid having to run through my XSLT file multiple time in the transformation process.  I also had to convert some number formats to use period as decimal point instead (due to language specific settings), so I made a script which changes between period and comma.

It is a powerful tool to have in the XSLT toolbox.

XSLT in .NET

by Svelmoe 1. June 2009 13:39

I have been working quite a bit with doing XSLT on some large XML files lately.
During this I worked with the XslCompiledTransform class in .NET, which make transformations really easy and it works very fast.

An advantage of this class is also that it enables you to utilize scripts within your XSLT file, which enables you to make for example C# functions, for various tasks. I’ll write more about that in a later blog entry to keep this one simple and to the point.

The syntax (in vb.net) for doing a transformation using XslCompiledTransform is as simple as the following:

    'Create settings which eanble scripting in the XSLT file
    
Dim xmlSettings As New 
XsltSettings
    xmlSettings.EnableScript 
= True
    
'create a XML reader for the XLST file
    
Dim xsltFile As XmlReader XmlReader.Create("XSLT FILE"
)
    
'create a Transform object
    
Dim xslTransform As New 
XslCompiledTransform
    
'Load XSLT file with Settings into transform object
    
xslTransform.Load(xsltFilexmlSettingsNothing
)
    
'Do the transformation.
    
xslTransform.Transform("INPUT XML FILE""OUTPUT XML FILE")
  

The main disadvantage I’ve found for using this transformation is the huge memory usage it uses.
In my own situation, the process used about 3.5 times as much memory as my source XML file, meaning that a source file about 450MB my .NET process was killed on a 32 bit computer with an out of memory exception.

The actual memory usage will of course vary depending on how complex your transformation is, so the 3.5 number is not meant to be nothing more than an indicator that it is memory intensive.
It is however very fast, and I managed to transform very large files in a manner of seconds, thus if you can live with the memory consumption it is quite effective.

String comparison performance, and regular expression, in vb.net

by Svelmoe 26. May 2009 16:50

Having to do some optimizing of processes over the last period of time, I decided to do some quick benchmark of the various string comparisons, to see how they performened against each other.
The ones I was interested in was the String.Equal and String.Compare, so I decided to make some quick testing.

I made a WinForm and used the following code to test with:

      For i As Integer = 0 To 100000
            If String.Equals("item", "ITEM", StringComparison.InvariantCultureIgnoreCase) Then
                Debug.WriteLine("yes")
            End If
        Next
        For i As Integer = 0 To 100000
            If String.Equals("item", "ITEM", StringComparison.CurrentCultureIgnoreCase) Then
                Debug.WriteLine("yes")
            End If
        Next
        For i As Integer = 0 To 100000
            If String.Equals("item", "ITEM", StringComparison.OrdinalIgnoreCase) Then
                Debug.WriteLine("yes")
            End If
        Next
        For i As Integer = 0 To 100000
            If String.Compare("item", "ITEM", True) = 0 Then
                Debug.WriteLine("yes")
            End If
        Next
        For i As Integer = 0 To 100000
            If String.CompareOrdinal("item", "item") = 0 Then
                Debug.WriteLine("yes")
            End If
        Next
        Dim regex As New System.Text.RegularExpressions.Regex("item", System.Text.RegularExpressions.RegexOptions.Compiled Or System.Text.RegularExpressions.RegexOptions.IgnoreCase)
        For i As Integer = 0 To 100000
            If regex.IsMatch("item") Then
                Debug.WriteLine("yes")
            End If
        Next


The specifics of the code aren’t that interesting, it was mostly to create some comparable numbers, so I use just one string “item” to compare to “ITEM” (except for CompareOrdinal, which is mostly there as a benchmark).

Anyways I was quite surprised at the numbers when I ran the code through RedGate’s ANTS performance profiler.



For the String.Equals with the various options, the following numbers were meassured:
StringComparison.InvariantCultureIgnoreCase gave 51.490ms (the actual number is irrelevant, it is the relative difference I’m interested in)

StringComparison.CurrentCultureIgnoreCase gave 65.747ms which is close enough to the above that I’ll say those two are quite similar.

StringComparison.OrdinalIgnoreCase however only took 12.378 for the same amount of iterations and true checks. This surprised me a bit.

String.Compare took 66.004ms, which is similar to the CurrentCultureIgnoreCase.

CompareOrdinal only took 8.056ms, but of course is case sensitive, so it doesn’t quite match up to this situation (unless you spend less time running a ToUpper on your compare clauses).

RegEx.IsMatch took a staggering 375.127ms with compiled and ignore clause, but then again – you shouldn’t use regular expression for something as trivial as this anyway. Regular expression is a very powerful tool in its own right, this was just to compare.

The big surprise is that there is such a big difference between using StringComparison.OrdinalIgnoreCase in your String.Equals compared to the other options. I’ll refer to the msdn documentation for the specifics of the different types (http://msdn.microsoft.com/en-us/library/system.stringcomparison.aspx) , but shallowly said - the Ordinal as the name says ignores culture specific matching.

So if that is acceptable in a given situation, using String.Equals with OrdinalIgnoreCase is by far the best option when comparing strings.

Again note the numbers aren’t numerically important, the relative difference existed as I ran the code several times, with OrdinalIgnoreCase winning out significantly each time.
In a production function I had made, I was able to shave several percent off my execution time, simply by switching from String.Compare to String.Equals with OrdinalIgnoreCase option used.
That was an easy way of gaining performance in my book.

VB.NET and the WITH statement

by Svelmoe 20. April 2009 20:23

I love using the WITH statement in VB.NET/ASP.NET because it eases up on the typing and helps “group together” functionality.
However, I found a fun little something when using the WITH statement, which I wanted to share.

It seems that you can assign a new object reference within a WITH statement to the specific object, however you can’t assign values to said new reference. Strange indeed, but I’m sure there’s some underlying reason.
Here some code to illustrate.

Suppose I have a class:

Private Class Test
        Private m_Text As String

        Public Property TextValue() As String
            Get
                Return m_Text
            End Get
            Set(ByVal value As String)
                m_Text = value
            End Set
        End Property
End Class

Then I have some code which uses this class in a WITH statement:

Dim obj As New Test()
obj.TextValue = "Test"
  For i As Integer = 0 To 10
   With obj
     If Not String.IsNullOrEmpty(.TextValue) Then
          System.Diagnostics.Debug.WriteLine("VALUE: " & .TextValue)
    Else
         System.Diagnostics.Debug.WriteLine("VALUE NOTHING")
    End If
    obj = New Test()
    .TextValue = "test" & i
   End With
Next

When run this provides the output:
VALUE: Test
VALUE NOTHING

And "nothing" for every subsequent run.
So it is possible to assign a new reference to the “obj” object reference, but the assignment of the new TextValue is ignored.

Not that usefull, but fun enough in my book :) (yes, I’m a geek

Email validate

by Svelmoe 12. September 2007 13:57

This is a semi-strong validation of e-mails for danish national characters as well. It is not perfect, but decent if needing a solid validating of an email, and I am constantly updateing it for personal use.

Note: Beware of the line breaks added

 ^[0-9a-zA-ZæøåÆØÅ][\w\.\-_æøåÆØÅ]*[a-zA-Z0-9æøåÆØÅ\.\-]@
a-zA-Z0-9æøåÆØÅ]([\w\.\-_æøåÆØÅ][a-zA-Z0-9æøåÆØÅ])*\.
[a-zA-ZæøåÆØÅ][a-zA-ZæøåÆØÅ\.]*[a-zA-Z]$


Yes, I know it is (far) from perfect, but it works for some of the reasons I encounter.
Also - remember, sometimes a loose validation is much better, if you can't validate completely - however, there are times where a stronger, more restrictive validation is useful.

 

At least for me :) 

Find HTML tags

by Svelmoe 30. August 2007 14:01

Some regular expression for finding HTML tags in code.

It is - as always is the case with regular expression in my view - not perfect, but it'll do for fast, simple parsing.

Find HTML tags:
<[^>]*>

This can be modified easy to find HTML tags except for anchor tags (for example):
<[^>aA]*>

 

Numbers in regular expression.

by Svelmoe 23. August 2007 14:04

Made these regular expressions some time ago to parse/validate numbers in text.

Validate number with comma as decimal pointer, and period as group separator:
^(\d+|([1-9]|[1-9]\d|[1-9]\d{2})(\.\d{3})*)(,\d{1,2})?$

Validate number with period as decimal pointer and comma as group separator:
^(\d+|([1-9]|[1-9]\d|[1-9]\d{2})(,\d{3})*)(\.\d{1,2})?$


Hope they are useful.

 

Trap Enter (or any other key).

by Svelmoe 12. August 2007 17:28

This is in the same line of thinking as the Hook F5 mention.

Sometimes it is usefull to "trap" a key - especially enter - and to do something other then the normal form submit or what ever.

function trapEnter(e)
{
  var keycode;
  if (window.event) keycode = window.event.keyCode;
  else if (e) keycode = e.which;
  else return true
  if (keycode == 13)
  { 

    //If enter should do nothing
    /*
    e.returnValue = false;
    e.cancel = true;
    return false;
    */
    //Otherwise - do stuff
  }
  return true;
}

 

Hook F5

by Svelmoe 11. August 2007 17:25

Removes functionality of F5 (refresh) on a an entire page. Useful with forms etc.

You can remove pretty much any keycode you so choose, but be careful. Users of a website aren't acustomed to having functionality changed/removed, so weigh the benefits with possible consequences.

//Yes. You did read right, no function.
if (document.all)
{
  //for IE browser
  document.onkeydown = function ()
  {
    if (event.keyCode == 116)
    {
      event.keyCode=0;
      return false;
    }
    return event.keyCode;
  }
}
else
{   //for FireFox/Netscape (others?)
  document.onkeypress = function (evt)
  {
    if(evt.keyCode == 116)
    { return false; }
    return evt.keyCode;
  }
}

Powered by BlogEngine.NET 1.4.5.0
Theme by Extensive SEO

About Svelmoe

My real name is Allan Svelmøe Hansen.

I live in Denmark, where I work as a developer for hedal:kruse:brohus using SQL Server and the .NET framework since 2004. Svelmoe.dk is a place for my every day thoughts and reactions and the occasional technical blog entry.

I also blog about SQL and MS SQL Server but have moved those posts to www.sqlstuff.dk so in case you are looking for more about that, please visit that website.