• Mark-101232 (9/24/2012)


    Unrolling the loop yields a small performance gain. Still doesn't handle NULLs or -2147483648 though.

    Unrolling the loop is an interesting idea, I will have a play with that in a minute to see if it works the same for me. I think I prefer the loop though - it's neater to my mind.

    Handling NULL and -2147483648 is another good point (though the original test rig can produce neither value, in my defence).

    The point I was looking to make is that expression evaluation in T-SQL is interpreted and therefore quite slow.

    It is amazing that passing a value out to CLR and back is faster, even without working hard to find an optimal .NET algorithm.

    Anyway, updated code to handle all values and NULL below:

    CREATE ASSEMBLY Test

    FROM 0x4D5A90000300000004000000FFFF0000B800000000000000400000000000000000000000000000000000000000000000000000000000000000000000800000000E1FBA0E00B409CD21B8014CCD21546869732070726F6772616D2063616E6E6F742062652072756E20696E20444F53206D6F64652E0D0D0A2400000000000000504500004C010300274C60500000000000000000E00002210B0108000008000000060000000000006E2600000020000000400000000040000020000000020000040000000000000004000000000000000080000000020000000000000300408500001000001000000000100000100000000000001000000000000000000000001C2600004F00000000400000A802000000000000000000000000000000000000006000000C000000802500001C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000080000000000000000000000082000004800000000000000000000002E7465787400000074060000002000000008000000020000000000000000000000000000200000602E72737263000000A80200000040000000040000000A0000000000000000000000000000400000402E72656C6F6300000C0000000060000000020000000E0000000000000000000000000000400000420000000000000000000000000000000050260000000000004800000002000500A0200000E004000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001330030039000000010000110F00280500000A2C067E0600000A2A160A0F00280700000A0B2B0C06071F0A5D580A071F0A5B0B072DF106162F0406652B0106730800000A2A1E02280900000A2A00000042534A4201000100000000000C00000076322E302E35303732370000000005006C00000044010000237E0000B00100006C01000023537472696E6773000000001C03000008000000235553002403000010000000234755494400000034030000AC01000023426C6F620000000000000002000001471502000900000000FA2533001600000100000007000000020000000200000001000000090000000400000001000000010000000200000000000A0001000000000006003D0036000A00650050000600970084000F00AB0000000600DA00BA000600FA00BA000A003D0122010000000001000000000001000100010010001800000005000100010050200000000096006E000A0001009520000000008618780011000200000001007E00190078001500290078001B0031007800110039007800110011005201680111005D016C01110062017001110078001B000900780011002000230020002E000B0079012E00130082012E001B008B0174010480000000000000000000000000000000001801000002000000000000000000000001002D0000000000020000000000000000000000010044000000000000000000003C4D6F64756C653E004461746162617365332E646C6C0055736572446566696E656446756E6374696F6E73006D73636F726C69620053797374656D004F626A6563740053797374656D2E446174610053797374656D2E446174612E53716C54797065730053716C496E7433320053756D446967697473002E63746F7200496E7075740053797374656D2E446961676E6F73746963730044656275676761626C6541747472696275746500446562756767696E674D6F6465730053797374656D2E52756E74696D652E436F6D70696C6572536572766963657300436F6D70696C6174696F6E52656C61786174696F6E734174747269627574650052756E74696D65436F6D7061746962696C69747941747472696275746500446174616261736533004D6963726F736F66742E53716C5365727665722E5365727665720053716C46756E6374696F6E417474726962757465006765745F49734E756C6C004E756C6C006765745F56616C7565000003200000000000E58AE8812A08674882CB590B906DDF360008B77A5C561934E089060001110911090320000105200101111104200101088146010004005455794D6963726F736F66742E53716C5365727665722E5365727665722E446174614163636573734B696E642C2053797374656D2E446174612C2056657273696F6E3D322E302E302E302C2043756C747572653D6E65757472616C2C205075626C69634B6579546F6B656E3D623737613563353631393334653038390A446174614163636573730000000054557F4D6963726F736F66742E53716C5365727665722E5365727665722E53797374656D446174614163636573734B696E642C2053797374656D2E446174612C2056657273696F6E3D322E302E302E302C2043756C747572653D6E65757472616C2C205075626C69634B6579546F6B656E3D623737613563353631393334653038391053797374656D446174614163636573730000000054020F497344657465726D696E6973746963015402094973507265636973650103200002030611090320000804070208080801000200000000000801000800000000001E01000100540216577261704E6F6E457863657074696F6E5468726F777301000000000000274C60500000000002000000800000009C2500009C07000052534453FA3B49E3B829D24C859CA14C76F908B103000000633A5C55736572735C5061756C2057686974655C446F63756D656E74735C56697375616C2053747564696F20323031305C50726F6A656374735C4461746162617365335C4461746162617365335C6F626A5C52656C656173655C4461746162617365332E706462004426000000000000000000005E26000000200000000000000000000000000000000000000000000050260000000000000000000000005F436F72446C6C4D61696E006D73636F7265652E646C6C0000000000FF2500204000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001001000000018000080000000000000000000000000000001000100000030000080000000000000000000000000000001000000000048000000584000004C02000000000000000000004C0234000000560053005F00560045005200530049004F004E005F0049004E0046004F0000000000BD04EFFE00000100000000000000000000000000000000003F000000000000000400000002000000000000000000000000000000440000000100560061007200460069006C00650049006E0066006F00000000002400040000005400720061006E0073006C006100740069006F006E00000000000000B004AC010000010053007400720069006E006700460069006C00650049006E0066006F0000008801000001003000300030003000300034006200300000002C0002000100460069006C0065004400650073006300720069007000740069006F006E000000000020000000300008000100460069006C006500560065007200730069006F006E000000000030002E0030002E0030002E00300000003C000E00010049006E007400650072006E0061006C004E0061006D00650000004400610074006100620061007300650033002E0064006C006C0000002800020001004C006500670061006C0043006F00700079007200690067006800740000002000000044000E0001004F0072006900670069006E0061006C00460069006C0065006E0061006D00650000004400610074006100620061007300650033002E0064006C006C000000340008000100500072006F006400750063007400560065007200730069006F006E00000030002E0030002E0030002E003000000038000800010041007300730065006D0062006C0079002000560065007200730069006F006E00000030002E0030002E0030002E0030000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000C000000703600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

    WITH PERMISSION_SET = SAFE;

    GO

    CREATE FUNCTION dbo.SumDigits

    (@Input integer)

    RETURNS integer

    AS EXTERNAL NAME Test.UserDefinedFunctions.SumDigits;

    Source:

    [font="Courier New"]public static SqlInt32 SumDigits(SqlInt32 Input)

    {

        if (Input.IsNull)

        {

            return SqlInt32.Null;

        }

        int sum = 0;

        for (int n = Input.Value; n != 0; sum += n % 10, n /= 10) ;

        return new SqlInt32(sum >= 0 ? sum : -sum);

    }

    [/font]