CSharp - Generic's

Разговоры на любые темы: вы можете обсудить здесь какой-либо сайт, найти единомышленников или просто пообщаться...
Dmitriy2003
Постоялец
Постоялец
 
Сообщения: 690
Зарегистрирован: 27.05.2003 (Вт) 22:47
Откуда: Deutschland

CSharp - Generic's

Сообщение Dmitriy2003 » 23.05.2008 (Пт) 23:21

Код: Выделить всё
using System;
using System.Collections;
using System.Collections.Generic;

namespace SimpleTiming
{
    class Program
    {
        /* Насколько же медленнее происходят операции при
         * упаковке/распаковке ?
         *
         * Суть вопроса - одна умная книга утверждает что Упаковка/распаковка
         * вешь хорошая однако в плане производительности настоящая кака.
         * В теории я полностью согласен и это очевидно, однако на практике
         * почему-то при моих замерениях на (E6300 1Gb Ram)
         * при 1 000 000 операций время всегда одно и тоже.
         *
         * может показаться странным зачем тест если и из теории
         * все понятно, ну скажу так конструкции типа
         *
         * public delegate TResult Action<TInput, TResult>(TInput x, TInput y)
         *
         * лично для меня чтение кода не облегчают вот и хочется понять
         * сколькоже я потеряю в производительности используя не обобщенные
         * методы, классы и делегаты и.т.п.
        */
        static void Main(string[] args)
        {
            int c, x;
            DateTime startTimeArray, endTimeArray;
            TimeSpan resultArray;

            c = Int32.Parse(args[0]);   
            ArrayList arrayList = new ArrayList(c);

            startTimeArray = DateTime.Now; 
            for (int i = 0; i < arrayList.Capacity; i++)
            {
                arrayList.Add(i);
            }
            foreach (int e in arrayList)
            {
                x = e;
            }
            endTimeArray = DateTime.Now;
           
            resultArray = endTimeArray - startTimeArray;
            Console.WriteLine("Time to use ArrayList: {0}", resultArray.Ticks);

           
            DateTime startTimeList, endTimeList;
            TimeSpan resultList;
           
            List<int> list = new List<int>(c);
           
            startTimeList = DateTime.Now;
            for (int i = 0; i < list.Capacity; i++)
            {
                list.Add(i);
            }
            foreach (int e in list)
            {
                x = e;
            }
            endTimeList = DateTime.Now;
           
            resultList = endTimeList - startTimeList;
            Console.WriteLine("Time to use List<int>: {0}", resultList.Ticks);

            // Console.ReadLine(); 
        }
    }
}

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Сообщение ANDLL » 24.05.2008 (Сб) 14:29

Че-то не понятно, что ты пытаешься измерить?
Упаковка\распаковка происходит в обоих случаях, поэтому значение и одно и то же.
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

Dmitriy2003
Постоялец
Постоялец
 
Сообщения: 690
Зарегистрирован: 27.05.2003 (Вт) 22:47
Откуда: Deutschland

Сообщение Dmitriy2003 » 26.05.2008 (Пн) 15:49

если int тип по значению - то согласно книге List<int> - оптимизированн под int - и соответсвенно повышение производительности, поскольку в отличие от ArrayList который принимает object, операции типа

Код: Выделить всё

// хотя здесь преобразоваение может происходить неявно
// arrayList.Add(i) - все же оно происходит ???

arrayList.Add((object)i);
x = (int)i


не потребуется.

однако на практике как я уже писал - время во обоих случаях одинаковое, вот я и в сомнении - может я чего напутал ?

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Сообщение ANDLL » 26.05.2008 (Пн) 16:41

Преобразование типа не требует много времени. Много времени требует упаковка(это совсем не перобразование типов), есть в обоих кусках.
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

Dmitriy2003
Постоялец
Постоялец
 
Сообщения: 690
Зарегистрирован: 27.05.2003 (Вт) 22:47
Откуда: Deutschland

Сообщение Dmitriy2003 » 26.05.2008 (Пн) 17:26

Чета я теперь совсем запутался!

если тип ссылочный то он храниться в куче.
если тип int - тип по значению - то он хранится в стеке. NET Framework позволяет приводить типы (кастинг) - в наше случае мы же не приводим int к object (т.е. в моей книге это называется упаковкой Boxing/Unboxing), а упаковываем int в object.

поскольку object тип по ссылке, данные будут храниться в куче
и значит если int i = 5; значение переменной i = 5;, то после
object x = (object)i; в переменной x будет ссылка на ячейку памяти в управляемой куче.

Так вот здесь положительным образом и проявляются обощенные классы (Generic).

List<int> тогда будет строго типизирован (или даже оптимизированн для работы int) - следовательно для добавления и для чтения елементов в и из списка не потребуется операций (Упаковки/распаковки) элементов в object и обратно в int.

вот собственно так описана теория в
Professional C# 2005 with .NET 3.0
Christian Nagel, Bill Evjen, Jay Glynn, Karli Watson, Morgan Skinner
ISBN: 978-0-470-12472-7


Для простоты оставим в покое делегатов, методы и класы.

Вот мне и хотелось узнать какова реальная потеря производительности от этих упаковок и распаковок - потому то я попробовал замерить - однако результат мне ничего не сказал. Теоретически я в полне понимаю что она есть однако насколько велик выигрыш - это было мне интересно.

Ну да ладно у обобщенных классов есть столько преимуществ - что только ради них и стоит их использовать.

хотя- бы ради этого
Код: Выделить всё
list.ForEach(delegate(int i) {Console.WriteLine(i);});

Думаю вопрос исчерпан. :) спасибо за инфу.
Последний раз редактировалось Dmitriy2003 26.05.2008 (Пн) 18:40, всего редактировалось 1 раз.

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Сообщение ANDLL » 26.05.2008 (Пн) 17:38

List<int> тогда будет строго типизирован (или даже оптимизированн для работы int) - следовательно для добавления и для чтения елементов в и из списка не потребуется операций (Упаковки/распаковки) элементов в object и обратно в int.
Вот это неверно.
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

Dmitriy2003
Постоялец
Постоялец
 
Сообщения: 690
Зарегистрирован: 27.05.2003 (Вт) 22:47
Откуда: Deutschland

Сообщение Dmitriy2003 » 26.05.2008 (Пн) 18:32

Так - что же получается автор книги передает неверное представление о платформе ? :roll:

А что-же тогда верно ?

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Сообщение ANDLL » 26.05.2008 (Пн) 18:49

Либо "автор книги передает неверное представление о платформе", либо ты просто его не так понял.
Верно то, что в случае с generic типами упаковка все равно происходит. Генерики нужны для повышения стабильности кода, а не для ускорения.
И второй важный момент в том, что генерики в .NET\java очень сильно отличаются от генериков в C++(где код действительно оптимизируется под каждый тип).
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

Dmitriy2003
Постоялец
Постоялец
 
Сообщения: 690
Зарегистрирован: 27.05.2003 (Вт) 22:47
Откуда: Deutschland

Сообщение Dmitriy2003 » 26.05.2008 (Пн) 18:56

ANDLL писал(а):Либо "автор книги передает неверное представление о платформе", либо ты просто его не так понял.
Верно то, что в случае с generic типами упаковка все равно происходит. Генерики нужны для повышения стабильности кода, а не для ускорения.
И второй важный момент в том, что генерики в .NET\java очень сильно отличаются от генериков в C++(где код действительно оптимизируется под каждый тип).


Проясним ситуацию :roll:

C# 2005 и платформа .NET 3.0 для профессионалов писал(а):Изображение

Изображение

Изображение

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Сообщение ANDLL » 26.05.2008 (Пн) 19:33

Ну ты наверное и сам убедился, что никакой производительности не повышается
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

Dmitriy2003
Постоялец
Постоялец
 
Сообщения: 690
Зарегистрирован: 27.05.2003 (Вт) 22:47
Откуда: Deutschland

Сообщение Dmitriy2003 » 26.05.2008 (Пн) 19:40

Увы, это так время у меня всегда одно и тоже :(

Nord777
Гуру
Гуру
Аватара пользователя
 
Сообщения: 1144
Зарегистрирован: 22.02.2004 (Вс) 13:15
Откуда: Подольск

Сообщение Nord777 » 26.05.2008 (Пн) 20:04

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

Увы, это так время у меня всегда одно и тоже

Это вы ребят погорячились.
Код: Выделить всё
    Const Count As Integer = 10000000
    Dim SW As New System.Diagnostics.Stopwatch
    Dim GenList As New List(Of Integer)
    Dim Lst As New ArrayList


    '--------------------------
    SW.Start()
    For i As Integer = 1 To Count
      Lst.Add(i)
    Next
    SW.Stop()
    MsgBox(SW.ElapsedMilliseconds.ToString)

    '--------------------------
    SW.Reset()
    SW.Start()
    For i As Integer = 1 To Count
      GenList.Add(i)
    Next
    SW.Stop()
    MsgBox(SW.ElapsedMilliseconds.ToString)


результат:
1429 ms
79 ms
Microsoft Visual Studio 2008
Microsoft .NET Framework 3.5

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Сообщение ANDLL » 26.05.2008 (Пн) 20:33

Гм. Неужто .NET умнее чем я думал?
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

Dmitriy2003
Постоялец
Постоялец
 
Сообщения: 690
Зарегистрирован: 27.05.2003 (Вт) 22:47
Откуда: Deutschland

Сообщение Dmitriy2003 » 26.05.2008 (Пн) 21:15

Однако разница - радикальная! Видать напортачил я с алгоритмом :)
Всем спасибо за участие!


Вернуться в Народный треп

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 44

    TopList