2015-06-14 3 views
2

У меня есть следующий код, который генерирует два массива без дубликатов целых чисел на основе отношения. Коды работают отлично, но для файла с 4000 строк это занимает некоторое время.Создайте два массива не дублирующих чисел

//Train & Test numbers 
int train = (int)(((double)Settings.Default.TrainingRatio/100) * inputLines.Count()); 
int test = inputLines.Count() - train; 

//Train & Test list 
Random rnd = new Random(); 
var trainList = Enumerable.Range(1, inputLines.Count()).OrderBy(x => rnd.Next()).Take(train).ToList(); 
var testList = new List<int>(); 
for (int i = 1; i <= inputLines.Count(); i++) 
{ 
    if (!trainList.Contains(i)) 
     testList.Add(i); 
} 

И еще хуже, это то, как я прочитал эти строки:

foreach (var n in trainList) 
{ 
    objDataintilizer.GenerateMasterLableFile(inputLines.Skip(n - 1).Take(1).First().ToString()); 
} 
Могли

любой другой способ советы, которые могли бы иметь более высокую производительность.

+0

Какой тип 'inputLines'? –

+0

его список , содержащие строки – ykh

+0

Как вы читаете эти строки? –

ответ

3

Каждый раз, когда ваш код вызывает inputFiles.Count(), вы эффективно перечитывать весь файл, поскольку File.ReadLines использует отложила выполнение, и вы не материализовать его. Так как вам нужен весь список в памяти в любом случае, вместо этого используйте File.ReadAllLines, который возвращает string[] и имеет свойство Length, которое является операцией O (1) вместо O (N).

Затем, вместо того, чтобы использовать List<int> для вашего trainList, используйте HashSet<int>, который будет быстрее для поиска с Contains:

public static class EnumerableExtensions 
{ 
    public static HashSet<T> ToHashSet(this IEnumerable<T> enumerable) 
    { 
     return new HashSet<T>(enumerable); 
    } 
} 

Random rnd = new Random(); 
var trainList = Enumerable.Range(1, inputLines.Length) 
          .OrderBy(x => rnd.Next()) 
          .Take(train) 
          .ToHashSet(); 

var testList = new List<int>(); 
for (int i = 1; i <= inputLines.Length; i++) 
{ 
    if (!trainList.Contains(i)) 
     testList.Add(i); 
} 
+0

Я использовал часть вашего решения, но я не могу использовать ReadAllLines, потому что мой файл огромен и вызовет исключение OutOfMemoryException. У меня есть вопрос, как вы думаете, я могу улучшить чтение строк? – ykh

+0

Если файл огромен, вы можете работать с подмножествами файла с помощью 'ReadLines'. Вместо этого вы можете перебирать строки за строкой, создавая список таким образом. –

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