Быстро читать и анализировать данные


По состоянию на сейчас, я использую этот код, чтобы открыть файл и прочитать его в список и проанализируйте, что список в строку[]:

string CP4DataBase = "C:\\Program\\Line Balancer\\FUJI DB\\KTS\\KTS - CP4 - Part Data Base.txt";
CP4DataBaseRTB.LoadFile(CP4DataBase, RichTextBoxStreamType.PlainText);
string[] splitCP4DataBaseLines = CP4DataBaseRTB.Text.Split('\n');
List<string> tempCP4List = new List<string>();
string[] line1CP4Components;

foreach (var line in splitCP4DataBaseLines)
    tempCP4List.Add(line + Environment.NewLine);

string concattedUnitPart = "";
foreach (var line in tempCP4List)
{
    concattedUnitPart = concattedUnitPart + line;
    line1CP4PartLines++;
}

line1CP4Components = new Regex("\"UNIT\",\"PARTS\"", RegexOptions.Multiline)
                    .Split(concattedUnitPart)
                    .Where(c => !string.IsNullOrEmpty(c)).ToArray();

Я интересно, если есть быстрый способ сделать это. Это только один из файлов я открываю, так это повторяется минимум 5 раз, чтобы открыть и правильно загрузить списки.

Минимальный размер импортируемого файла сейчас составляет 257 КБ. Самый большой файл-это 1,803 КБ. Эти файлы будут только расти, как время идет, как они используются для моделирования базы данных, а пользователь будет постоянно добавлять к ним.

Итак, мой вопрос: есть ли быстрый способ, чтобы делать все вышеперечисленное код?



457
2
задан 13 декабря 2011 в 09:12 Источник Поделиться
Комментарии
4 ответа

Часть кода, что делает его очень медленно, это:

string concattedUnitPart = "";
foreach (var line in tempCP4List)
{
concattedUnitPart = concattedUnitPart + line;
line1CP4PartLines++;
}

Вы не должны объединять большие строки, как, что. Строка становится все длиннее и длиннее для каждой итерации, и он копируется в новую строку каждый раз.

Если Вы читаете файл, 1,8 МБ, который состоит из линий которых варьируется от 50 до 100 знаков, вы будет копирование около 10 000 МБ данных перед вами результат.

Также Весы очень плохо, поэтому, когда файлы, расти он будет медленнее расти в геометрической прогрессии. Для обработки файл, который занимает 5 Мб вы будет копирование около 80 000 МБ данных.

Джеймс предложено сделать замену, кажется, хороший вариант. Если вы хотите Split и join, можно использовать строку.Присоединяйтесь к методу:

string[] splitCP4DataBaseLines = CP4DataBaseRTB.Text.Split('\n');
string concattedUnitPart = String.Join(Environment.NewLine, splitCP4DataBaseLines) + Environment.NewLine;

5
ответ дан 14 декабря 2011 в 04:12 Источник Поделиться

Если я читаю это правильно, Вы читаете текст с символов новой строки, разбиение на символы перехода на новую строку, добавив символы новой строки и затем конкатенация строк снова вместе?

почему не вместо:

CP4DataBaseRTB.Text.Replace('\n', Environment.NewLine);

2
ответ дан 14 декабря 2011 в 02:12 Источник Поделиться

Есть несколько моментов, которые я бы сделал на это - какой-то касаемо производительности и некоторые просто о лучших практик кодирования.

Во-первых, когда жесткого кодирования путь к файлу и когда вы не требует каких-либо символов, то проще просто объявить строку с символом '@'. Это означает, что вам не нужно, чтобы избежать обратной косой черты.

string CP4DataBase = @"C:\Program\Line Balancer\FUJI DB\KTS\KTS - CP4 - Part Data Base.txt";

Далее, где вы построили tempCP4List, вы могли бы взять двух альтернативных подходов. Первая использует возможности конструктора параметр или список.Способность собственность, которая явно указывает начальный размер списка. Это полезно как при построении списка с помощью добавить(), если содержимое списка превышает возможности, новый массив будет создан в список , чтобы разместить новый элемент. При работе с большими коллекциями данных, это может вызвать проблемы с производительностью. Так вот, я хотел бы использовать:

List<string> tempCP4List = new List<string>(splitCP4DataBaseLines.Length);

- или -

List<string> tempCP4List = new List<string>();
tempCP4List.Capacity = splitCP4DataBaseLines.Length;

Поочередно, вы могли бы использовать LINQ для построения списка сразу, используя:

List<string> tempCP4List = new List<string>(splitCP4DataBaseLines.Select(line => line + Environment.NewLine));

Еще один момент, о котором уже упоминалось на Guffa является конкатенация строк в том, как вы с concattedUnitPart = concattedUnitPart + линия; очень много памяти процесса. В этом случае, как Guffa и Анна Лира совершали хорошие моменты в отношении к использованию строки.Присоединяйтесь к(...) или класса StringBuilder. Если вы выполните небольшую тестовую программу с большими объемами текстовых данных, вы увидите, насколько резкое улучшение производительности, это может доставить.

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

line1CP4Components = new Regex("\"UNIT\",\"PARTS\"", RegexOptions.Multiline)
.Split(new string[1] { concattedUnitPart }, StringSplitOptions.RemoveEmptyEntries);

Обратите внимание на использование StringSplitOptions.RemoveEmptyEntries вариант. Об этом говорит строка.Сплит(...) метод, чтобы делать то, что ваш где(...) оговорки.

2
ответ дан 14 декабря 2011 в 08:12 Источник Поделиться

Вот мои 5 копеек на все ответы. Когда вы используете регулярные выражения больше, чем после того, как он всегда помогает объявить регулярное выражение в поле с скомпилированный вариант:

private static readonly Regex splitRegex = new Regex("\"UNIT\",\"PARTS\"", RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Compiled);

1
ответ дан 14 декабря 2011 в 11:12 Источник Поделиться