Using an OR/M I map a lot of rows from database to array of objects (~300k). In these objects some properties are marked with special attribute [Signed]
. Row-by-row I combine them in string, calculate salted MD5 of string and compare to hash I received from database.
Everything was working pretty okay for a long time, but now my website started to work quite slow and I run a profiler. It says the slowest method of whole website is ValueToString
. I optimized it as much as I can. Is it possible to optimize it more? I want to mention I do not need exact string representation so feel free to change formatters.
Another question if I will redesign everything from string
to byte[]
- will it speed up the process, what do you think?
static string ValueToString(object value)
{
if (value == null)
return "";
string value_string = value as string;
if (value_string != null)
return value_string;
int value_int;
if (value is Enum) {
value_int = (int)value;
if (value_int >= 0 && value_int <= 255)
return hexStringTable[((int)value)];
if (value_int == -1)
return "FFFFFFFF";
// Actually, we are never here.
return value_int.ToString("X");
}
decimal value_decimal;
if (TryCast(value, out value_decimal))
return value_decimal.ToString().TrimEnd('0');
if (TryCast(value, out value_int))
return value_int.ToString("X");
DateTime value_DateTime;
if (TryCast(value, out value_DateTime))
return value_DateTime.Ticks.ToString("X");
// We are never here for slow table.
return Convert.ToString(value,
CultureInfo.InvariantCulture);
}
static bool TryCast<T>(object o, out T r)
{
if (o is T) {
r = (T)o;
return true;
}
r = default(T);
return false;
}
static readonly string[] hexStringTable = new string[]
{
"00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "0A", "0B", "0C", "0D", "0E", "0F",
"10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "1A", "1B", "1C", "1D", "1E", "1F",
"20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "2A", "2B", "2C", "2D", "2E", "2F",
"30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "3A", "3B", "3C", "3D", "3E", "3F",
"40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "4A", "4B", "4C", "4D", "4E", "4F",
"50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "5A", "5B", "5C", "5D", "5E", "5F",
"60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "6A", "6B", "6C", "6D", "6E", "6F",
"70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "7A", "7B", "7C", "7D", "7E", "7F",
"80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "8A", "8B", "8C", "8D", "8E", "8F",
"90", "91", "92", "93", "94", "95", "96", "97", "98", "99", "9A", "9B", "9C", "9D", "9E", "9F",
"A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", "A8", "A9", "AA", "AB", "AC", "AD", "AE", "AF",
"B0", "B1", "B2", "B3", "B4", "B5", "B6", "B7", "B8", "B9", "BA", "BB", "BC", "BD", "BE", "BF",
"C0", "C1", "C2", "C3", "C4", "C5", "C6", "C7", "C8", "C9", "CA", "CB", "CC", "CD", "CE", "CF",
"D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7", "D8", "D9", "DA", "DB", "DC", "DD", "DE", "DF",
"E0", "E1", "E2", "E3", "E4", "E5", "E6", "E7", "E8", "E9", "EA", "EB", "EC", "ED", "EE", "EF",
"F0", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "FA", "FB", "FC", "FD", "FE", "FF"
};
TryCast<T>()
method. why would you do that for Decimal and a Long? I am pretty sure that both of those have their own method for that. \$\endgroup\$return ((int)value).ToString("X");
(before my optimisation it wasvalue_Enum.ToString("d")
-- worked 2 times slower, now is slow too) andreturn value_decimal.ToString("0.############################", CultureInfo.InvariantCulture);
. \$\endgroup\$