2015-06-22 2 views
0

Следующий фрагмент преобразует данные xml в данные csv в приложении обработки данных. element - XElement. В настоящее время я пытаюсь оптимизировать производительность приложения и задаюсь вопросом, могу ли я как-то объединить две операции, которые будут выполняться ниже: В конечном счете, я все же хочу получить доступ к строковому значению join и элементам значений в списке, потому что они используются позже для других целей. Не уверен, что это выполнимо. Любая помощь будет оценена!тип преобразования производительность оптимизируется?

Первая операция в основном разделяет XML-данные всех тегов и просто возвращает текстовые данные между ними или за их пределами. Он также проверяет форматирование. Вторая операция принимает данные XML и удаляет все разрывы и пробелы строк, если они существуют в пределах первых нескольких символов данных.

IEnumerable<string> values = new List<string>(); 
     values = element.DescendantNodes().OfType<XText>() 
     .Select(v => Regex.Replace(v.Value, "\\s+", " ")).ToList(); 

string joined = string.Concat(element.ToString().Split().Take(3)) + string.Join(" ", element. 
     ToString().Split().Skip(3)); 

ответ

0
IEnumerable<string> values = new List<string>(); 
values = … 

Вероятно, не будет большой проблемой, но зачем создавать новый List<string>() просто выбросить. Заменить это либо:

IEnumerable<string> values; 
values = … 

Если вам нужно values определенные в предыдущем объеме, или же просто:

Enumerable<string> values = … 

Тогда позже:

….Select(v => Regex.Replace(v.Value, "\\s+", " ")).ToList(); 

ли вам это действительно нужно, чтобы быть списком? Сравните скорость только с:

….Select(v => Regex.Replace(v.Value, "\\s+", " ")); 

Есть моменты, когда это медленнее, и есть моменты, когда он просто не будет работать, но есть много раз, когда ToList() это просто пустая трата времени и памяти.

string joined = string.Concat(
    element.ToString().Split().Take(3)) 
    + string.Join(" ", element.ToString().Split().Skip(3)); 

Первая вещь, почему ты звонишь ToString()Split() и дважды ?:

var splitOnWhiteSpace = element.ToString().Split(); 
string joined = string.Concat(
    splitOnWhiteSpace.Take(3)) 
    + string.Join(" ", splitOnWhiteSpace.Skip(3)); 

Мы, вероятно, может оптимизировать Join тоже с индивидуальным подходом:

var elString = element.ToString(); 
var buffer = new StringBuilder(element.Length - 2); //Can't be larger, unlikely to be much smaller so obtain necessary space in advance. 
using(var en = elString.Split().GetEnumerator()) 
{ 
    int count = 0; 
    while(en.MoveNext() && ++count != 4) 
    buffer.Append(en.Current); 
    while(en.MoveNext()) 
    buffer.Append(en.Current).Append(' '); 
} 
string joined = buffer.ToString(); 

Если бы это было будучи пораженным несколькими петлями, я бы подумал о том, чтобы удерживать буфер между циклами (Clear() после каждого использования, а не для создания новый).

Если строка была разделена на большой размер, я мог бы рассмотреть пользовательскую версию Split(), которая повторялась бы через строку, испускающую только те части, которые нужны, а не создание массива в каждом проходе, но я бы не стал беспокоиться об этом до тех пор, пока я Сначала я попытался сделать более очевидные улучшения.

+0

спасибо, ваши предложения немного улучшили производительность! – sparta93

+0

Время обработки для ГБ данных длилось от ~ 7 минут до ~ 6,4 минут – sparta93

+0

Если вы замените свой подход 'XElement' на тот, который использует' XmlReader', и делает это потоковым способом ('yield return'ing results as it получает их), вы, вероятно, сможете сделать гораздо лучше; «XmlReader» используется, но обычно быстрее. –

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