2012-02-02 6 views
1

Я использовал long.TryParse, но переключился на регулярное выражение. В настоящее время для сообщения 123 + K требуется 7+ миллисекунд. 7+ миллисекунд - от XElement.Parse до конца методов foreach.Как я могу улучшить скорость этого запроса LINQ?

Stopwatch s1 =Stopwatch.StartNew(); 
XElement element = XElement.Parse(xml);  

string pattern = @"\b\d+\b"; 
Regex r = new Regex(pattern); 

IEnumerable<XElement> elementsWithPossibleCCNumbers = element 
    .Descendants() 
    .Where(d => d.Attributes() 
     .Where(a => a.Value.Length >= 13 && 
       a.Value.Length <= 16 && 
       r.IsMatch(a.Value)).Count() == 1) 
    .Select(x => x); 

foreach(var x in elementsWithPossibleCCNumbers) 
{ 
    foreach(var a in x.Attributes()) 
    { 
     //Check if the value is a number 
     if(r.IsMatch(a.Value)) 
     { 
      //Check if value is the credit card 
      if(a.Value.Length >= 13 && a.Value.Length <= 16) 
      { 
       a.Value = Regex.Replace(a.Value, @"\b\d{13,16}\b", match => 
        new String('*', match.Value.Length - 4) + 
        match.Value.Substring(match.Value.Length - 4) 
       ); 
     } 
     else //If value is not a credit card, replace it with *** 
       a.Value = Regex.Replace(a.Value ,@"\b\d+\b", "***"); 
     } 
    } 
} 

xml = element.ToString(); 
s1.Stop(); 

XElement.Parse(xml); занимает между 2 - 3 мс.

Запрос LINQ занимает от 0,004 до 0,005 мс.

Операторы foreach занимают от 4 до 5 мс.

+0

Действительно только 7MS ? Звучит неплохо. – user7116

+0

@sixlettervariables - Да, для одного сообщения это хорошо, но у меня есть тонна этих прихожей, поэтому его объем сообщений. – Xaisoft

+0

Вы пробовали статическое скомпилированное регулярное выражение? –

ответ

0

Возможно, вы захотите рассмотреть предварительное компиляцию своего регулярного выражения. Статья здесь: http://en.csharp-online.net/CSharp_Regular_Expression_Recipes%E2%80%94Compiling_Regular_Expressions объясняет про и недостатки компиляции регулярного выражения довольно хорошо.

+0

На странице не указана ваша ссылка ... –

+0

Извините, проблема с копией. Я обновил ссылку. – afrischke

1

Похоже, вы делаете два поиска и замены:

  1. Replace каждый CC номер с *-х и 4 последние цифры
  2. заменяет любые другие „CC-иш“ номер на том же элемент с *.

Один подход должен был бы сделать XLinq работать немного сложнее для вас:

// you're not using the elements, ignore them, just get the attributes 
foreach (var atr in xelt.Descendants() 
         .Where(e => e.Attributes() 
            .Any(a => a.Value.Length >= 13 
              && a.Value.Length <= 16)) 
         .SelectMany(e => e.Attributes())) 
{ 
    // static basicDigits = new Regex(@"\b\d+\b", RegexOptions.Compiled); 
    // static ccDigits = new Regex(@"\b\d{13,16}\b", RegexOptions.Compiled); 
    if (ccDigits.IsMatch(atr.Value)) 
    { 
     atr.Value = ccDigits.Replace(
      atr.Value, 
      mm => new String('*', mm.Value.Length - 4) 
        + mm.Value.Substring(mm.Value.Length - 4)); 
    } 
    else 
    { 
     atr.Value = basicDigits.Replace(atr.Value, "***"); 
    } 
} 

// using 150k XML (1k nodes/5k attrs, 3 attr/node avg, avg depth 4 nodes) 
// with 10% match rate: 
// - 25.7 MB/s (average 100 trials) 
// - 61 attributes/ms 

Пример входного XML:

<item f1="abc123abc" f2="helloooo 1234567" f3="abc123abc"> 
    <item f1="abc123abc" f2="helloooo 1234567" f3="abc123abc" real1="4444555566667777" /> 
    <item f1="abc123abc" f2="helloooo 1234567" f3="abc123abc" /> 
    ruBTMjSesurMsP6lK2jg 
</item> 

Выходные:

<item f1="abc123abc" f2="helloooo 1234567" f3="abc123abc"> 
    <item f1="abc123abc" f2="helloooo ***" f3="abc123abc" real1="************7777" /> 
    <item f1="abc123abc" f2="helloooo 1234567" f3="abc123abc" /> 
    ruBTMjSesurMsP6lK2jg 
</item> 
+0

Я сейчас пытаюсь это сделать. Я думал о том, чтобы просто получить атрибуты, но не знал, как это сделать. Я дам вам знать. – Xaisoft

+0

Хорошо, я заметил несколько вещей. Время не изменилось, оно в значительной степени оставалось прежним, а номер кредитной карты заменялся, но другие cc-ish номера сохраняют свою ценность. – Xaisoft

+0

Любопытно, как вы придумали эти показатели в своих комментариях под кодом? – Xaisoft

Смежные вопросы