Запуталса, помогите розобратса

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by boka111, 11 Sep 2011.

  1. boka111

    boka111 New Member

    Joined:
    26 Aug 2011
    Messages:
    1
    Likes Received:
    0
    Reputations:
    0
    Нужно засечь время деструкции нескольких милионов обектов в с шарп, тоисть деструтор нужно вызвать явно, а не ждать пока GC соберет мусор, иначе время будет не коректное, нашол в инете специальный шаблон проектирование Dispose но не наю как ево внедрить, если кто знает помогите
    вот код:
    Code:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Diagnostics;
    
    namespace ConsoleApplication1
    {
        public class ExperimentalClass : IDisposable 
        {
            protected bool disposed;
            //insure the access modifier is protected so that derived classes can also make use of //the same 
            protected virtual void Dispose(bool disposing)
            {
                if (disposed) return;
                lock (this)
                {
                    if (disposing)
                    {
                        // Release Managed resources here 
                    }
                    // Release UnManaged resources here 
                    //call the base object's Dispose protected method 
                    Dispose(disposing); 
                    disposed = true;
                }
            }
    
            public void Dispose() 
            { 
                Dispose(true); GC.SuppressFinalize(this); 
            } 
    
            private double SomeFeild;
            public double SomeField1;
            public double SomeMethod(long SomeData)
            {
                return SomeData;
            }
            public ExperimentalClass(long i)
            {
                SomeFeild = i + 1;
            }
            ~ExperimentalClass()
            {
                SomeFeild = double.MinValue;
                Console.WriteLine("Oh fuck");
                //Dispose(false);
            }
        }
        
        class Program
        {
            static void PrintMemory()
            {
                
                Process[] processlist = Process.GetProcessesByName("ConsoleApplication1.vshost");
                Console.WriteLine("Memory costs: " + processlist[0].PagedMemorySize64 / 1024.0 / 1024.0 + " mb");
            }
            static void Main(string[] args)
            {
                long nClasses;
                DateTime dStart, dFinish;
                PrintMemory();
                Console.WriteLine("Type the quntity of objectsthat will be created");
                string snClasses = Console.ReadLine();
                if (!long.TryParse(snClasses, out nClasses))
                    Console.WriteLine("Not an integer!");
                ExperimentalClass[] MyClasses = new ExperimentalClass[nClasses];
                {
                    DateTime t1 = DateTime.Now;
                    for (long i = 0; i < nClasses; i++) // СОЗДАЮ ДОХУЯ ОБЕКТОВ
                        MyClasses[i] = new ExperimentalClass(i);
                    DateTime t2 = DateTime.Now; //ЗАСЕКАЮ ВРЕМЯ И ДЕЛАЮ ЕКСПЕРЕМЕНТ ВЫЗОВА   ОБЕКТОВ КЛАСУ
                    TimeSpan dt = t2 - t1;
                    PrintMemory();
                    Console.WriteLine("Creation time of " + nClasses + " objects is: " + dt);
    
                    t1 = DateTime.Now; //ЗАСЕКАЮ ВРЕМЯ И ДЕЛАЮ ЕКСПЕРЕМЕНТ ВЫЗОВА МЕТОДОВ КЛАСА
                    for (long i = 0; i < nClasses; i++)
                        MyClasses[i].SomeField1 = MyClasses[i].SomeMethod(i);
                    t2 = DateTime.Now;
                    dt = t2 - t1;
                    Console.WriteLine("Time of operation in  " + nClasses + " objects is: " + dt);
                    PrintMemory();
    
                    dStart = DateTime.Now; //ЗАСЕКАЮ ВРЕМЯ И ДЕЛАЮ ЕКСПЕРЕМЕНТ ВЫЗОВА ДЕСТРУКТОРОВ
                }
    
                //ЗДЕСЬ НУЖНО ВЫЗВАТЬ ДЕСТРУКТОРЫ ВСЕХ ОБЕКТОВ
                dFinish = DateTime.Now;
                TimeSpan dt1 = dStart - dFinish;
                Console.WriteLine("Destruction time of " + nClasses + " objects is: " + dt1);
                PrintMemory();
                Console.ReadKey();
    
    
    
    
    
            }
        }
    }
    
     
  2. Bers

    Bers Member

    Joined:
    17 May 2010
    Messages:
    78
    Likes Received:
    30
    Reputations:
    26
    Помогаю - правильно пишется "запутался", "разобраться"

    1. Выучи русский язык, тебя читать невозможно
    2. Деструкторов в .NET нет, есть финализаторы, не путай
    2. На кой хер тебе замерять время дескрукции объектов? Бредовая, вообще говоря, мысль
    3. Вызов деструкторов замерять вообще невозможно - они вызывается ТОЛЬКО из GC. Итого - ты собрался померять производительность GC. Скажу сразу - это настолько синтетический тест, что он просто бессмысленен.

    Ниже я позволил себе прокомментировать твой говнокод.

    Code:
        public class ExperimentalClass : IDisposable 
        {
            protected virtual void Dispose(bool disposing)
            {
                if (disposed) return;
                lock (this)
                {
                    if (disposing)
                    {
                        // Release Managed resources here 
                    }
                    // Release UnManaged resources here 
                    //call the base object's Dispose protected method 
                    Dispose(disposing); 
                    disposed = true;
                }
            }
    
    Ну отлично, ты тестируешь время работы lock(). В однопоточном варианте. Крутой тест, очень показательный.

    Code:
            private double SomeFeild;
    
    FEILD?!

    Code:
    ~ExperimentalClass()
            {
                SomeFeild = double.MinValue;
    
    Смысл? Ты задаешь значение поля объекта, который уже де-факто умирает. Эта память через несколько тактов будет освобождена

    Code:
                Console.WriteLine("Oh fuck"); 
    
    А это что за бред? Ты всерьез полагаешь, что вызов Console.WriteLine() из херпоймикакого потока никак не исказит твои замеры?

    Code:
                    DateTime t1 = DateTime.Now;
    
    Замерять время DateTime'ом - точность будет плюс-минус лапоть. Смотри System.Diagnotics.Stopwatch

    Code:
                    for (long i = 0; i < nClasses; i++) // СОЗДАЮ ДОХУЯ ОБЕКТОВ
                        MyClasses[i] = new ExperimentalClass(i);
                    DateTime t2 = DateTime.Now; //ЗАСЕКАЮ ВРЕМЯ И ДЕЛАЮ ЕКСПЕРЕМЕНТ ВЫЗОВА   ОБЕКТОВ КЛАСУ
    
    Ты вообще писать умеешь? Блин, за что ты меня так мучаешь, что я тебе сделал?

    Code:
                    Console.WriteLine("Creation time of " + nClasses + " objects is: " + dt);
    
    Мерять время создания объектов не очень интересно - в .NET куча очень быстро создает объекты

    Code:
                    t1 = DateTime.Now; //ЗАСЕКАЮ ВРЕМЯ И ДЕЛАЮ ЕКСПЕРЕМЕНТ ВЫЗОВА МЕТОДОВ КЛАСА
                    for (long i = 0; i < nClasses; i++)
                        MyClasses[i].SomeField1 = MyClasses[i].SomeMethod(i);
                    t2 = DateTime.Now;
                    dt = t2 - t1;
                    Console.WriteLine("Time of operation in  " + nClasses + " objects is: " + dt);
    
    Опять - что ты меряешь? Затраты на прямой вызов невиртуального метода? А зачем, ежу понятно, что они исчезающе малы.

    Code:
                    dStart = DateTime.Now; //ЗАСЕКАЮ ВРЕМЯ И ДЕЛАЮ ЕКСПЕРЕМЕНТ ВЫЗОВА ДЕСТРУКТОРОВ
                }
    
                //ЗДЕСЬ НУЖНО ВЫЗВАТЬ ДЕСТРУКТОРЫ ВСЕХ ОБЕКТОВ
    

    И наконец-то феерия! Если ты хочешь проверить, за сколько времени освободится память - дерни вручную GC:
    Code:
    GC.Collect();
    GC.WaitForPendingFinalizers();
    
    Но сразу говорю:
    1. Твой тест просто некорректен, он не даст разумных цифр
    2. Такой тест вообще сильно синтетический, он не дает понимания, как оно работает и как его использовать.

    Короче, не страдай фигней, а почитай Рихтера, у него отлично описано, как работает CLR-куча.
     
    #2 Bers, 11 Sep 2011
    Last edited: 11 Sep 2011