Глубокое клонирование в C # занимает больше времени для выполнения каждого вызова - PullRequest
0 голосов
/ 19 апреля 2011

Я пытаюсь глубоко клонировать список из 100 объектов с несколькими свойствами, я использую приведенный ниже код для выполнения глубокого клонирования.Создание списка и клонирование списка происходит в цикле, поэтому каждый раз при цикле список меняет свое содержимое, но остается фиксированным на 100 объектах.

Проблема заключается в том, что при каждом цикле клонирование списка занимает экспоненциально больше времени, чем в прошлый раз.

public static Main ()
{

List<Chromosome<Gene>> population = Population.randomHalfAndHalf(rand, data, 100, opset);

        for (int i = 0; i < numOfGenerations; i++)
        {
                   offSpring = epoch.runEpoch(rand, population, SelectionMethod.Tournament, opset);
                    clone = DeepClone<List<Chromosome<Gene>>>(population);
                    clone.AddRange(offSpring);
                    population = fixPopulation(rand, clone, SelectionMethod.Tournament, 100);
        }

//....REST OF CODE....

}


public static T DeepClone<T>(T obj)
    {
        object result = null;

        using (var ms = new MemoryStream())
        {
            var formatter = new BinaryFormatter();
            formatter.Serialize(ms, obj);
            ms.Position = 0;

            result = (T)formatter.Deserialize(ms);
            ms.Close();
        }
        return (T)result;
    }

Некоторые из вас могут подумать, почему я даже клонирую объект, если могу писать поверх первоначальной совокупности.Это правильная точка, которую я исследовал, но когда я это делаю, происходит то, что цикл выполняется идеально в течение примерно 8 итераций при первом запуске, затем он работает на холостом ходу и ничего не делает, поэтому я его останавливаю.В следующий раз, когда я выполняю его, он проходит 9 итераций и остановок, идеалов, ничего не делает и т. Д. Каждый раз вокруг цикла.Если у кого-то есть какие-либо идеи относительно того, почему это происходит, пожалуйста, поделитесь, поскольку я действительно не понимаю, почему это происходит.

Но моя главная проблема заключается в том, что время клонирования объекта заметно увеличивается каждый раз, когда проходит цикл, сначала на несколько секунд, затем в конечном итоге до 5 минут и т. Д.

Любое тело имеетидеи относительно того, почему это происходит?

РЕДАКТИРОВАТЬ Я профилировал приложение, пока оно выполнялось, большая часть работы над 90% выполняется BinaryFormatter.Deserialize (memoryStream) и здесьэто исправить население, не делая ничего слишком сложного, что могло бы способствовать решению этой проблемы.

private static List<Chromosome<Gene>> fixPopulation(Random rand, List<Chromosome<Gene>> oldPopulation, SelectionMethod selectionMethod, int populationSize)
    {
        if (selectionMethod == SelectionMethod.Tournament)
        {
            oldPopulation.Sort();
        }
        else
        {
            //NSGAII sorting method
        }

        oldPopulation.RemoveRange(populationSize, (oldPopulation.Count - populationSize));

        for (int i = 0, n = populationSize / 2; i < n; i++)
        {
            int c1 = rand.Next(populationSize);
            int c2 = rand.Next(populationSize);

            // swap two chromosomes
            Chromosome<Gene> temp = oldPopulation[c1];
            oldPopulation[c1] = oldPopulation[c2];
            oldPopulation[c2] = temp;
        }

        return oldPopulation;
    }

1 Ответ

0 голосов
/ 19 апреля 2011

Вы можете использовать двоичную сериализацию для создания быстрого клона ваших объектов:

посмотрите на это:

public Entity Copy()
        {
            System.IO.MemoryStream memoryStream = new System.IO.MemoryStream();

            System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bFormatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
            bFormatter.Serialize(memoryStream, this);
            memoryStream.Seek(0, System.IO.SeekOrigin.Begin);
            IEntityForm entity= (IEntityForm)bFormatter.Deserialize(memoryStream);
            return entity;
        }

действительно просто и работает!

...