Re: Очередь фиксированного размера с вытеснением старых
От: Kerbadun  
Дата: 18.01.11 23:01
Оценка: +1 :)
Здравствуйте, Аноним, Вы писали:

А>Требуется отображать последние 10000 элементов. Записи порождаются достаточно быстро — около 1000 в минуту их нужно логировать.


А>Пока вижу варант с Dictionary<int, MeasureData > и переменной с индексом как курсор текущей позиции.

А>Но есть несколько проблем — для новых значений создается новый MeasureData со своим DateTime что может съесть память. А также выборка из такого списка не очень удобна учитывая что нужно еще по дате в обратном порятке сортировать — лишние расчеты.

А>Есть ли готовые списки для этого ?


Это называется Circular Buffer. Можно либо написать, либо взять кем-то написанный.

На стандартных контейнерах наиболее разумное решение — LinkedList<>.

Quene — From Old English cwen "woman, wife, queen," or cwene "woman, wife, prostitute".


Особенно забавно в контексте этого значения выглядят идентификаторы TestQuene и MyQuene.

Когда он умрет, его мозг заспиртуют в стакане
Re[5]: Очередь фиксированного размера с вытеснением старых
От: LaptevVV Россия  
Дата: 18.01.11 23:43
Оценка: +2
Здравствуйте, samius, Вы писали:

S>Здравствуйте, LaptevVV, Вы писали:


LVV>>Здравствуйте, Аноним, Вы писали:

А>>>>>Пока вижу варант с Dictionary<int, MeasureData > и переменной с индексом как курсор текущей позиции.
D>>>>Не совсем понятно, почему не подходит обыкновенный List<>?
А>>>тормозить будет при вставке элемента в начало или наоборот при удалении из начала.
LVV>>Читайте матчасть. Вставка и удаление из списка выполняются за константное время.
S>Речь о дотнете, в нем List-ом называется динамический массив. Соответственно время вставки/удаления линейное.

LVV>>Требует синхронизации доступа к буферу-контейнеру. Это — средствами API — в С++ стандартных средств пока нет.

S>Тема ведь в донтене
Да, я потом заметил, когда отослал...
Но ИМХО — это безобразие: вводить программеров в заблуждение такими названиями...
Повбывав бы!...
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[3]: Очередь фиксированного размера с вытеснением старых
От: Murom Россия  
Дата: 19.01.11 06:03
Оценка: +2
Здравствуйте, Аноним, Вы писали:

А>        static void TestLinkedList()
А>        {
А>            var queue = new LinkedList<object>();
А>            int cnt = 0;

А>            var sw = new System.Diagnostics.Stopwatch();
А>            sw.Start();
А>            for (int i = 0; i < 30000; i++)
А>            {
А>                queue.AddFirst(new object());
А>                if (queue.Count > 10000)
А>                    queue.RemoveLast();

А>                cnt += queue.ToArray().Count();
А>            }

А>            sw.Stop();

А>            Console.WriteLine(cnt);
А>            Console.WriteLine("LinkedList Time:" + sw.Elapsed);

А>        }
А>    }


Собственно вопрос — а что данный тест меряет?
Обрати внимание, что в тесте обычного списка и связного списка есть строка
cnt += queue.ToArray().Count();

Логично предположить, что для массива она выполняется за практически нулевое время, а для списка нет.
Т.е. ты померял конвертацию списка в массив, но никак не вставку элементов.

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

На счет .Reverse — у тебя ж данные упорядоченные, т.е. ты всегда знаешь, когда надо идти в прамом порядке, когда в обратном. Следовательно вместо того, чтобы разворачивать массивы, просто пройти по нему в другую сторону.
- Eugeny
Re[5]: Очередь фиксированного размера с вытеснением старых
От: samius Япония http://sams-tricks.blogspot.com
Дата: 18.01.11 22:19
Оценка: :)
Здравствуйте, Аноним, Вы писали:

А>>>Вполне шустро работает. Меньше миллисекунды..196 тиков всего.

А>>>А он не двигает все элементы при удаленни чтоли ?
S>>Двигает. А Queue — нет.

А>вот кстати решил провести тест, получилось


А>Quene Time:00:00:03.3552024

А>List Time:00:00:00.5903732

А>т.е. с Quene в 6 раз медленнее из-за необходимости Reverse()


А>если Reverse() убрать то получается чуть быстрее листа


А>Quene Time:00:00:00.3937243

А>List Time:00:00:00.5932789

А>
А>                cnt += quene.ToArray().Reverse().Count();
А>


Так работает вровень, а то и быстрее:
var array = quene.ToArray();
Array.Reverse(array);
cnt += array.Count();

250005000
Quene Time:00:00:00.6969832
250005000
List Time:00:00:00.7490250


P.S. А почему Quene через N?
Re: Очередь фиксированного размера с вытеснением старых
От: _d_m_  
Дата: 19.01.11 03:51
Оценка: +1
Здравствуйте, Аноним, Вы писали:

    /// <summary>
    /// Очередь с ограничением по кол-ву элементов
    /// </summary>
    /// <typeparam name="T"></typeparam>
    internal sealed class LimitedQueue<T> : Queue<T>
    {
        /// <summary>
        /// Максимальная емкость очереди
        /// </summary>
        private int MaxCapacity;

        /// <summary>
        /// Конструктор только такой
        /// </summary>
        /// <param name="_MaxCapacity">максимальное кол-во элементов в очереди</param>
        public LimitedQueue(int _MaxCapacity)
            : base(_MaxCapacity)
        {
            this.MaxCapacity = _MaxCapacity;
        }

        /// <summary>
        /// Заменяем базовую реализацию. Если очередь заполнена, то удаляем первый в ней элемент
        /// </summary>
        /// <param name="_item"></param>
        public new void Enqueue(T _item)
        {
            if( base.Count == this.MaxCapacity )
                base.Dequeue();

            base.Enqueue(_item);
        }
    }
Очередь фиксированного размера с вытеснением старых
От: Аноним  
Дата: 18.01.11 18:23
Оценка:
Требуется отображать последние 10000 элементов. Записи порождаются достаточно быстро — около 1000 в минуту их нужно логировать.

Пока вижу варант с Dictionary<int, MeasureData > и переменной с индексом как курсор текущей позиции.
Но есть несколько проблем — для новых значений создается новый MeasureData со своим DateTime что может съесть память. А также выборка из такого списка не очень удобна учитывая что нужно еще по дате в обратном порятке сортировать — лишние расчеты.

Есть ли готовые списки для этого ?
Re: Очередь фиксированного размера с вытеснением старых
От: samius Япония http://sams-tricks.blogspot.com
Дата: 18.01.11 18:59
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Требуется отображать последние 10000 элементов. Записи порождаются достаточно быстро — около 1000 в минуту их нужно логировать.


А>Пока вижу варант с Dictionary<int, MeasureData > и переменной с индексом как курсор текущей позиции.

А>Но есть несколько проблем — для новых значений создается новый MeasureData со своим DateTime что может съесть память. А также выборка из такого списка не очень удобна учитывая что нужно еще по дате в обратном порятке сортировать — лишние расчеты.

А>Есть ли готовые списки для этого ?

Есть стандартный FIFO контейнер — Queue<T>. Сортировать не надо, если складывать по мере порождения данных.
Re[2]: Очередь фиксированного размера с вытеснением старых
От: Аноним  
Дата: 18.01.11 19:28
Оценка:
Здравствуйте, samius, Вы писали:

S>Здравствуйте, Аноним, Вы писали:


А>>Требуется отображать последние 10000 элементов. Записи порождаются достаточно быстро — около 1000 в минуту их нужно логировать.


А>>Пока вижу варант с Dictionary<int, MeasureData > и переменной с индексом как курсор текущей позиции.

А>>Но есть несколько проблем — для новых значений создается новый MeasureData со своим DateTime что может съесть память. А также выборка из такого списка не очень удобна учитывая что нужно еще по дате в обратном порятке сортировать — лишние расчеты.

А>>Есть ли готовые списки для этого ?

S>Есть стандартный FIFO контейнер — Queue<T>. Сортировать не надо, если складывать по мере порождения данных.

Не совсем то. Ниже тестовый пример, может я неправильно с ней работаю.
Dequene будет съедать элемент, и второму потоку оно не достанется. самое старое значение должно вытесняться при вставке нового элемента а не при чтении.
Т.е. допустим нам не 10000 нужно записей а иметь "окно" только 5 последних записей.
Соотвественно сначала должно вывестись :

5,4,3,2,1 потом 6,5,4,3,2 , потом 7,6,5,4,3
в обоих потоках.



   class Program
    {
        static Queue<int> q;
        static object syncObj = new object();

        static void ShowLast5()
        {

                while (true)
                {
                    // это блокирока чтоб 2 потока по очереди показывали результат 5 сек кажды
                    lock( syncObj )
                    {
                        Console.Clear();
                        Console.WriteLine(string.Format("Last 5 Records from Thread {0}: ", System.Threading.Thread.CurrentThread.ManagedThreadId));
                        foreach (var i in q)
                            Console.WriteLine(i);

                        System.Threading.Thread.Sleep(5000);
                    }                
                }
        }

        static int newitem;
        static void Generate()
        {
            while (true)
            {
                q.Enqueue(newitem);
                newitem++;
                System.Threading.Thread.Sleep(15000);
            }

        }


        static void Main(string[] args)
        {
            
            q = new Queue<int>(5);
            q.Enqueue(1);
            q.Enqueue(2);
            q.Enqueue(3);
            q.Enqueue(4);
            q.Enqueue(5);

            newitem = 6;

            var t1 = new System.Threading.Thread(Generate);
            t1.Start();

            var t2 = new System.Threading.Thread(ShowLast5);
            t2.Start();
            var t3 = new System.Threading.Thread(ShowLast5);
            t3.Start();

            Console.ReadKey();
        }
    }
Re[3]: Очередь фиксированного размера с вытеснением старых
От: samius Япония http://sams-tricks.blogspot.com
Дата: 18.01.11 19:45
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, samius, Вы писали:


А>>>Есть ли готовые списки для этого ?

S>>Есть стандартный FIFO контейнер — Queue<T>. Сортировать не надо, если складывать по мере порождения данных.

А>Не совсем то. Ниже тестовый пример, может я неправильно с ней работаю.

А>Dequene будет съедать элемент, и второму потоку оно не достанется. самое старое значение должно вытесняться при вставке нового элемента а не при чтении.
В стартовом сообщении ничего о потоках не было...

А>Т.е. допустим нам не 10000 нужно записей а иметь "окно" только 5 последних записей.

А>Соотвественно сначала должно вывестись :

А>5,4,3,2,1 потом 6,5,4,3,2 , потом 7,6,5,4,3

А>в обоих потоках.

Не понял. Требуется что бы один и тот же контейнер, изменяемый в одном потоке отыграл все свои состояния в других потоках, которые выводят в консоль элементы?
Если так, то мне неясно, как здесь поможет Dictionary...

А>
А>   class Program
А>    {
А>    }
А>

В коде ошибки синхронизации, кроме того по нему не понятно, какая задача решается.
Re: Очередь фиксированного размера с вытеснением старых
От: dims12 http://www.relativity.ru
Дата: 18.01.11 20:12
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Пока вижу варант с Dictionary<int, MeasureData > и переменной с индексом как курсор текущей позиции.


Не совсем понятно, почему не подходит обыкновенный List<>?
Re[2]: Очередь фиксированного размера с вытеснением старых
От: Аноним  
Дата: 18.01.11 21:09
Оценка:
Здравствуйте, dims12, Вы писали:

D>Здравствуйте, Аноним, Вы писали:


А>>Пока вижу варант с Dictionary<int, MeasureData > и переменной с индексом как курсор текущей позиции.


D>Не совсем понятно, почему не подходит обыкновенный List<>?


тормозить будет при вставке элемента в начало или наоборот при удалении из начала.
Re[4]: Очередь фиксированного размера с вытеснением старых
От: Аноним  
Дата: 18.01.11 21:14
Оценка:
Здравствуйте, samius, Вы писали:

S>Здравствуйте, Аноним, Вы писали:


А>>Здравствуйте, samius, Вы писали:


А>>>>Есть ли готовые списки для этого ?

S>>>Есть стандартный FIFO контейнер — Queue<T>. Сортировать не надо, если складывать по мере порождения данных.

А>>Не совсем то. Ниже тестовый пример, может я неправильно с ней работаю.

А>>Dequene будет съедать элемент, и второму потоку оно не достанется. самое старое значение должно вытесняться при вставке нового элемента а не при чтении.
S>В стартовом сообщении ничего о потоках не было...

А>>Т.е. допустим нам не 10000 нужно записей а иметь "окно" только 5 последних записей.

А>>Соотвественно сначала должно вывестись :

А>>5,4,3,2,1 потом 6,5,4,3,2 , потом 7,6,5,4,3

А>>в обоих потоках.

S>Не понял. Требуется что бы один и тот же контейнер, изменяемый в одном потоке отыграл все свои состояния в других потоках, которые выводят в консоль элементы?

S>Если так, то мне неясно, как здесь поможет Dictionary...

А>>
А>>   class Program
А>>    {
А>>    }
А>>

S>В коде ошибки синхронизации, кроме того по нему не понятно, какая задача решается.

задача простая видеть последние N записей из разных потоков, старые записи должны из списка/очереди удаляться иначе их накопится очень много.

решение на Dictionary вижу примерно следующее.


public class MyQuene
{

    private Dictionary<int, MeasureData> quene;
    private int currentItem = 0;
    private int queneCapacity = 10000;

    public PushNewMeasure( p1, p2, p3 )
    {
        if ( currentItem >= queneCapacity )
        {
           currentItem=0;
        }

        quene[ currentItem ] = new MeasureData( p1, p2, p3 );
        currentItem++;
    }

    public MeasureData[] GetMeasures()
    {       
        return
        quene.Skip( currentItem ).Take( queneCapacity - currentItem).
          Union( quene.Take( currentItem ) )
          .Select ( i => i.Value).Reverse().ToArray();
    }
}
Re[2]: Очередь фиксированного размера с вытеснением старых
От: Аноним  
Дата: 18.01.11 21:23
Оценка:
Здравствуйте, dims12, Вы писали:

D>Здравствуйте, Аноним, Вы писали:


А>>Пока вижу варант с Dictionary<int, MeasureData > и переменной с индексом как курсор текущей позиции.


D>Не совсем понятно, почему не подходит обыкновенный List<>?


Вот блин. Оказывается он ничуть не тормозной
Вполне шустро работает. Меньше миллисекунды..196 тиков всего.
А он не двигает все элементы при удаленни чтоли ?
Re[5]: Очередь фиксированного размера с вытеснением старых
От: samius Япония http://sams-tricks.blogspot.com
Дата: 18.01.11 21:24
Оценка:
Здравствуйте, Аноним, Вы писали:

А>задача простая видеть последние N записей из разных потоков, старые записи должны из списка/очереди удаляться иначе их накопится очень много.


Полагаю, что с этого надо было начать.

А>решение на Dictionary вижу примерно следующее.


А>

А>public class MyQuene
А>{

А>    private Dictionary<int, MeasureData> quene;
А>    private int currentItem = 0;
А>    private int queneCapacity = 10000;

А>    public PushNewMeasure( p1, p2, p3 )
А>    {
А>        if ( currentItem >= queneCapacity )
А>        {
А>           currentItem=0;
А>        }

А>        quene[ currentItem ] = new MeasureData( p1, p2, p3 );
А>        currentItem++;
А>    }

А>    public MeasureData[] GetMeasures()
А>    {       
А>        return
А>        quene.Skip( currentItem ).Take( queneCapacity - currentItem).
А>          Union( quene.Take( currentItem ) )
А>          .Select ( i => i.Value).Reverse().ToArray();
А>    }
А>}

А>

Вообще говоря это решение обладает недостатками:
*) записи не удаляются
*) синхронизация отсутствует как класс
*) при добавлении очередного элемента и одновременном выполнении GetMeasures неминуемо исключение
*) записи не упорядоченны и берутся не последние
Re[3]: Очередь фиксированного размера с вытеснением старых
От: samius Япония http://sams-tricks.blogspot.com
Дата: 18.01.11 21:26
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, dims12, Вы писали:


D>>Здравствуйте, Аноним, Вы писали:


А>>>Пока вижу варант с Dictionary<int, MeasureData > и переменной с индексом как курсор текущей позиции.


D>>Не совсем понятно, почему не подходит обыкновенный List<>?


А>Вот блин. Оказывается он ничуть не тормозной

А>Вполне шустро работает. Меньше миллисекунды..196 тиков всего.
А>А он не двигает все элементы при удаленни чтоли ?
Двигает. А Queue — нет.
Re[3]: Очередь фиксированного размера с вытеснением старых
От: LaptevVV Россия  
Дата: 18.01.11 21:27
Оценка:
Здравствуйте, Аноним, Вы писали:
А>>>Пока вижу варант с Dictionary<int, MeasureData > и переменной с индексом как курсор текущей позиции.
D>>Не совсем понятно, почему не подходит обыкновенный List<>?
А>тормозить будет при вставке элемента в начало или наоборот при удалении из начала.
Читайте матчасть. Вставка и удаление из списка выполняются за константное время.
Кроме того, то, что я тут прочитал, наводит меня на мысль, что вполне можно обйтись стандартным деком, который тоже вставку и удаление на концах делает за константное время. А то, что вы тут говорите о потоках — это стандартная задача читатели-писатели. Требует синхронизации доступа к буферу-контейнеру. Это — средствами API — в С++ стандартных средств пока нет.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[4]: Очередь фиксированного размера с вытеснением старых
От: samius Япония http://sams-tricks.blogspot.com
Дата: 18.01.11 21:30
Оценка:
Здравствуйте, LaptevVV, Вы писали:

LVV>Здравствуйте, Аноним, Вы писали:

А>>>>Пока вижу варант с Dictionary<int, MeasureData > и переменной с индексом как курсор текущей позиции.
D>>>Не совсем понятно, почему не подходит обыкновенный List<>?
А>>тормозить будет при вставке элемента в начало или наоборот при удалении из начала.
LVV>Читайте матчасть. Вставка и удаление из списка выполняются за константное время.
Речь о дотнете, в нем List-ом называется динамический массив. Соответственно время вставки/удаления линейное.

LVV>Требует синхронизации доступа к буферу-контейнеру. Это — средствами API — в С++ стандартных средств пока нет.

Тема ведь в донтене
Re[6]: Очередь фиксированного размера с вытеснением старых
От: Аноним  
Дата: 18.01.11 21:33
Оценка:
Здравствуйте, samius, Вы писали:

S>Здравствуйте, Аноним, Вы писали:


А>>задача простая видеть последние N записей из разных потоков, старые записи должны из списка/очереди удаляться иначе их накопится очень много.


S>Полагаю, что с этого надо было начать.


А>>решение на Dictionary вижу примерно следующее.


А>>

А>>public class MyQuene
А>>{

А>>    private Dictionary<int, MeasureData> quene;
А>>    private int currentItem = 0;
А>>    private int queneCapacity = 10000;

А>>    public PushNewMeasure( p1, p2, p3 )
А>>    {
А>>        if ( currentItem >= queneCapacity )
А>>        {
А>>           currentItem=0;
А>>        }

А>>        quene[ currentItem ] = new MeasureData( p1, p2, p3 );
А>>        currentItem++;
А>>    }

А>>    public MeasureData[] GetMeasures()
А>>    {       
А>>        return
А>>        quene.Skip( currentItem ).Take( queneCapacity - currentItem).
А>>          Union( quene.Take( currentItem ) )
А>>          .Select ( i => i.Value).Reverse().ToArray();
А>>    }
А>>}

А>>

S>Вообще говоря это решение обладает недостатками:
S>*) записи не удаляются
так их и не нужно удалять, их всегда ровно 10000. Просто старые перезаписываются новыми а не вставляются/удаляются.

S>*) синхронизация отсутствует как класс

ну я не стал загромождать код синхронизацией тут как бы главное алгоритм очереди

S>*) при добавлении очередного элемента и одновременном выполнении GetMeasures неминуемо исключение

это из п.2. и следует поставить lock{} большого труда не составит

S>*) записи не упорядоченны и берутся не последние

записи как раз упорядочены по Index в порядке добавления, допустим index текущий = 5000, соотвественно запрос выберет с 5001-10000 и сделает union с 1-5000 записи — получится список в хронологическом порядке — ему делается reverse().


Но в общем мне понравилось обычное решение с list.Insert(0,...) и list.RemoveAt(1001) его и буду использовать с большой вероятностью
Re[7]: Очередь фиксированного размера с вытеснением старых
От: samius Япония http://sams-tricks.blogspot.com
Дата: 18.01.11 21:37
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, samius, Вы писали:


S>>Вообще говоря это решение обладает недостатками:

S>>*) записи не удаляются
А>так их и не нужно удалять, их всегда ровно 10000. Просто старые перезаписываются новыми а не вставляются/удаляются.
С чего бы это они перезаписываются?

S>>*) синхронизация отсутствует как класс

А>ну я не стал загромождать код синхронизацией тут как бы главное алгоритм очереди

S>>*) при добавлении очередного элемента и одновременном выполнении GetMeasures неминуемо исключение

А>это из п.2. и следует поставить lock{} большого труда не составит

S>>*) записи не упорядоченны и берутся не последние

А>записи как раз упорядочены по Index в порядке добавления, допустим index текущий = 5000, соотвественно запрос выберет с 5001-10000 и сделает union с 1-5000 записи — получится список в хронологическом порядке — ему делается reverse().
Записи в словаре хранятся не в порядке вставки.

А>Но в общем мне понравилось обычное решение с list.Insert(0,...) и list.RemoveAt(1001) его и буду использовать с большой вероятностью

Сдвиг на каждое добавление? Так чем Queue-то не устроил?
Re[8]: Очередь фиксированного размера с вытеснением старых
От: Аноним  
Дата: 18.01.11 21:44
Оценка:
Здравствуйте, samius, Вы писали:

S>Здравствуйте, Аноним, Вы писали:


А>>Здравствуйте, samius, Вы писали:


S>>>Вообще говоря это решение обладает недостатками:

S>>>*) записи не удаляются
А>>так их и не нужно удалять, их всегда ровно 10000. Просто старые перезаписываются новыми а не вставляются/удаляются.
S>С чего бы это они перезаписываются?

ну посмотри алгоритм внимательно там значение currentItem бегает по кругу в пределах 0-9999

        if ( currentItem >= queneCapacity )
        {
           currentItem=0;
        }

        quene[ currentItem ] = new MeasureData( p1, p2, p3 );
        currentItem++;


соотвественно словарь сначала забивается 10000 элементами и больше уже не растет.




S>>>*) записи не упорядоченны и берутся не последние

А>>записи как раз упорядочены по Index в порядке добавления, допустим index текущий = 5000, соотвественно запрос выберет с 5001-10000 и сделает union с 1-5000 записи — получится список в хронологическом порядке — ему делается reverse().
S>Записи в словаре хранятся не в порядке вставки.

Ну вот это засада если так.

А>>Но в общем мне понравилось обычное решение с list.Insert(0,...) и list.RemoveAt(1001) его и буду использовать с большой вероятностью

S>Сдвиг на каждое добавление? Так чем Queue-то не устроил?
Ну я так понял что оно не двигает реально..может там связи обычные — но работает очень шустро. Проверил на 100000 записей что в 10 раз больше чем мне нужно — задержка всего 90 микросекунд.
Re[4]: Очередь фиксированного размера с вытеснением старых
От: Аноним  
Дата: 18.01.11 21:50
Оценка:
D>>>Не совсем понятно, почему не подходит обыкновенный List<>?

А>>Вот блин. Оказывается он ничуть не тормозной

А>>Вполне шустро работает. Меньше миллисекунды..196 тиков всего.
А>>А он не двигает все элементы при удаленни чтоли ?
S>Двигает. А Queue — нет.

Ну даже если и двигает то очень быстро..намного быстрее чем я ожидал.
Quene недостаток в получении "перевернутого списка" , с list переворачивать не придется
и все решение сводится для вставки
list.Insert(0, .. );
if ( list.Count > Capacity )
   list.Remove( Capacity );


для получения
/// чтоб копию создать
return list.ToArray();
Re[9]: Очередь фиксированного размера с вытеснением старых
От: samius Япония http://sams-tricks.blogspot.com
Дата: 18.01.11 21:55
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, samius, Вы писали:


S>>Здравствуйте, Аноним, Вы писали:


А>>>Здравствуйте, samius, Вы писали:


S>>С чего бы это они перезаписываются?


А>ну посмотри алгоритм внимательно там значение currentItem бегает по кругу в пределах 0-9999


А>соотвественно словарь сначала забивается 10000 элементами и больше уже не растет.

Да, проглядел

S>>Записи в словаре хранятся не в порядке вставки.


А>Ну вот это засада если так.


А>>>Но в общем мне понравилось обычное решение с list.Insert(0,...) и list.RemoveAt(1001) его и буду использовать с большой вероятностью

S>>Сдвиг на каждое добавление? Так чем Queue-то не устроил?
А>Ну я так понял что оно не двигает реально..может там связи обычные — но работает очень шустро. Проверил на 100000 записей что в 10 раз больше чем мне нужно — задержка всего 90 микросекунд.
Дак двигает реально, без вариантов двигает.
Re[5]: Очередь фиксированного размера с вытеснением старых
От: samius Япония http://sams-tricks.blogspot.com
Дата: 18.01.11 22:01
Оценка:
Здравствуйте, Аноним, Вы писали:

D>>>>Не совсем понятно, почему не подходит обыкновенный List<>?


А>>>Вот блин. Оказывается он ничуть не тормозной

А>>>Вполне шустро работает. Меньше миллисекунды..196 тиков всего.
А>>>А он не двигает все элементы при удаленни чтоли ?
S>>Двигает. А Queue — нет.

А>Ну даже если и двигает то очень быстро..намного быстрее чем я ожидал.

А>Quene недостаток в получении "перевернутого списка" , с list переворачивать не придется
Это лишь вопрос с какой стороны пробегать по результату.

А>и все решение сводится для вставки

А>
А>list.Insert(0, .. );
А>if ( list.Count > Capacity )
А>   list.Remove( Capacity );
А>

С Queue не длиннее

А>для получения

А>
А>/// чтоб копию создать
А>return list.ToArray();
А>

У Queue тоже есть метод ToArray()
Re[4]: Очередь фиксированного размера с вытеснением старых
От: Аноним  
Дата: 18.01.11 22:02
Оценка:
А>>Вполне шустро работает. Меньше миллисекунды..196 тиков всего.
А>>А он не двигает все элементы при удаленни чтоли ?
S>Двигает. А Queue — нет.

вот кстати решил провести тест, получилось

Quene Time:00:00:03.3552024
List Time:00:00:00.5903732

т.е. с Quene в 6 раз медленнее из-за необходимости Reverse()

если Reverse() убрать то получается чуть быстрее листа

Quene Time:00:00:00.3937243
List Time:00:00:00.5932789

    class Program
    {


        static void TestQuene()
        {
            var quene = new Queue<int>();
            int cnt = 0;

            var sw = new System.Diagnostics.Stopwatch();
            sw.Start();
            for (int i = 0; i < 30000; i++)
            {
                quene.Enqueue(i);
                if (quene.Count > 10000)
                    quene.Dequeue();

                cnt += quene.ToArray().Reverse().Count();
            }

            sw.Stop();

            Console.WriteLine(cnt);
            Console.WriteLine("Quene Time:" + sw.Elapsed);

        }

        static void TestList()
        {
            var quene = new List<int>();
            int cnt = 0;

            var sw = new System.Diagnostics.Stopwatch();
            sw.Start();
            for (int i = 0; i < 30000; i++)
            {
                quene.Insert(0, 99999999);
                if (quene.Count > 10000)
                    quene.RemoveAt(10000);

                cnt += quene.ToArray().Count();
            }

            sw.Stop();

            Console.WriteLine(cnt);
            Console.WriteLine("List Time:" + sw.Elapsed);

        }


        static void Main(string[] args)
        {
            TestQuene();
            TestList();
            Console.ReadKey();
        }
    }
Re[2]: Очередь фиксированного размера с вытеснением старых
От: Аноним  
Дата: 19.01.11 04:41
Оценка:
Здравствуйте, Kerbadun, Вы писали:

K>Здравствуйте, Аноним, Вы писали:


А>>Требуется отображать последние 10000 элементов. Записи порождаются достаточно быстро — около 1000 в минуту их нужно логировать.


А>>Пока вижу варант с Dictionary<int, MeasureData > и переменной с индексом как курсор текущей позиции.

А>>Но есть несколько проблем — для новых значений создается новый MeasureData со своим DateTime что может съесть память. А также выборка из такого списка не очень удобна учитывая что нужно еще по дате в обратном порятке сортировать — лишние расчеты.

А>>Есть ли готовые списки для этого ?


K>Это называется Circular Buffer. Можно либо написать, либо взять кем-то написанный.

и
K>На стандартных контейнерах наиболее разумное решение — LinkedList<>.

K>

Quene — From Old English cwen "woman, wife, queen," or cwene "woman, wife, prostitute".


K>Особенно забавно в контексте этого значения выглядят идентификаторы TestQuene и MyQuene.


Quene потому что спать пора
Что-то LinkedList как-то вяло отработал , еще я заменил int на object т.к. придется именно объекты добавлять.


250005000
Queue Time:00:00:02.1280462
250005000
List Time:00:00:00.9180821
250005000
LinkedList Time:00:00:02.3005547


   class Program
    {


        static void Testqueue()
        {
            var queue = new Queue<object>();
            int cnt = 0;

            var sw = new System.Diagnostics.Stopwatch();
            sw.Start();
            for (int i = 0; i < 30000; i++)
            {
                queue.Enqueue(new object());
                if (queue.Count > 10000)
                    queue.Dequeue();

                var array = queue.ToArray();
                Array.Reverse(array);
                cnt += array.Length;
            }

            sw.Stop();

            Console.WriteLine(cnt);
            Console.WriteLine("Queue Time:" + sw.Elapsed);

        }

        static void TestList()
        {
            var queue = new List<object>();
            int cnt = 0;

            var sw = new System.Diagnostics.Stopwatch();
            sw.Start();
            for (int i = 0; i < 30000; i++)
            {
                queue.Insert(0, new object());
                if (queue.Count > 10000)
                    queue.RemoveAt(10000);

                cnt += queue.ToArray().Count();
            }

            sw.Stop();

            Console.WriteLine(cnt);
            Console.WriteLine("List Time:" + sw.Elapsed);

        }


        static void TestLinkedList()
        {
            var queue = new LinkedList<object>();
            int cnt = 0;

            var sw = new System.Diagnostics.Stopwatch();
            sw.Start();
            for (int i = 0; i < 30000; i++)
            {
                queue.AddFirst(new object());
                if (queue.Count > 10000)
                    queue.RemoveLast();

                cnt += queue.ToArray().Count();
            }

            sw.Stop();

            Console.WriteLine(cnt);
            Console.WriteLine("LinkedList Time:" + sw.Elapsed);

        }

        static void Main(string[] args)
        {
            Testqueue();
            TestList();
            TestLinkedList();
            Console.ReadKey();
        }
    }
Re[3]: Очередь фиксированного размера с вытеснением старых
От: Kerbadun  
Дата: 19.01.11 07:08
Оценка:
Про ToArray() верно заметили.

LinkedList<> я имел в виду для того, что его можно не переворачивать.

Если бы переворачивать не нужно было, можно было бы использовать Queue<>.

Интересно, что Queue<> внутри реализована как кольцевой буфер на массиве, который автоматически растет (за O(N), ага). И еще ее нельзя обойти задом наперед. Все-таки, в дотнете дебиловатые контейнеры.

Когда он умрет, его мозг заспиртуют в стакане
Re[5]: Очередь фиксированного размера с вытеснением старых
От: SanyaVB  
Дата: 19.01.11 09:11
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, samius, Вы писали:


S>>Здравствуйте, Аноним, Вы писали:


А>>>Здравствуйте, samius, Вы писали:


А>>>>>Есть ли готовые списки для этого ?

S>>>>Есть стандартный FIFO контейнер — Queue<T>. Сортировать не надо, если складывать по мере порождения данных.

А>>>Не совсем то. Ниже тестовый пример, может я неправильно с ней работаю.

А>>>Dequene будет съедать элемент, и второму потоку оно не достанется. самое старое значение должно вытесняться при вставке нового элемента а не при чтении.
S>>В стартовом сообщении ничего о потоках не было...

А>>>Т.е. допустим нам не 10000 нужно записей а иметь "окно" только 5 последних записей.

А>>>Соотвественно сначала должно вывестись :

А>>>5,4,3,2,1 потом 6,5,4,3,2 , потом 7,6,5,4,3

А>>>в обоих потоках.

S>>Не понял. Требуется что бы один и тот же контейнер, изменяемый в одном потоке отыграл все свои состояния в других потоках, которые выводят в консоль элементы?

S>>Если так, то мне неясно, как здесь поможет Dictionary...

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

    class LimitedQueue 
    {
        object[] m_elements;
        int m_indexPosition;

        public LimitedQueue(int _capacity)
        {
            Capacity = _capacity;
            m_elements = new object[Capacity];
            m_indexPosition = 0;
            Count = 0;
        }

        public void Add(object _element)
        {
            m_elements[m_indexPosition] = _element;
            m_indexPosition++;
            if (m_indexPosition == Capacity)
                m_indexPosition = 0;
            if (Count != Capacity)
                Count++;
        }

        public object this[int _index]
        {
            get
            {
                if (_index >= Count || _index < 0)
                    throw new IndexOutOfRangeException();
                int indexPositionToArray;
                indexPositionToArray = (m_indexPosition + _index) % Capacity;
                return m_elements[indexPositionToArray];
            }
        }

        public int Capacity
        {
            get;
            private set;
        }

        public int Count
        {
            get;
            private set;
        }
    }


Можно также наследоваться от IEnumerable и уже здесь сделать потокобезопасность
Или задача состоит в том, чтобы использовать уже готовые списки
Re[3]: Очередь фиксированного размера с вытеснением старых
От: dims12 http://www.relativity.ru
Дата: 19.01.11 09:21
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Вполне шустро работает. Меньше миллисекунды..196 тиков всего.

А>А он не двигает все элементы при удаленни чтоли ?

Ну он как-то блоками работает. Заводится блок, скажем, длиной 100 позиций, в нём помнится, где конец и где начало. При удалении с головы сдвигается указатель на начало, при добавлении в хвост -- на конец. Если элементов становится больше, то происходит реорганизация. Я думаю как-то так. В любом случае, это внутренняя кухня. Мы должны руководствоваться мануалом:

If Count is less than Capacity, this method is an O(1) operation. If the capacity needs to be increased to accommodate the new element, this method becomes an O(n) operation, where n is Count.

То есть, долго будет работать только при необходимости увеличивать размер свыше Capacity.

Это -- самое эффективное решение, когда надо одновременно и обращаться по индексу и быстро добавлять/удалять элементы. Если не нужно обращаться по индексу, то можно использовать LinkedList -- это ещё быстрее.

This method is an O(1) operation.

Скорее всего, он Вам тоже подойдёт, потому что для отображения адресовать по индексу не нужно, а сканировать по цепочке LinkedList позволяет быстро.
Re[7]: Очередь фиксированного размера с вытеснением старых
От: dims12 http://www.relativity.ru
Дата: 19.01.11 09:31
Оценка:
Здравствуйте, Аноним, Вы писали:

А>>> public MeasureData[] GetMeasures()

А>>> {
А>>> return
А>>> quene.Skip( currentItem ).Take( queneCapacity — currentItem).
А>>> Union( quene.Take( currentItem ) )
А>>> .Select ( i => i.Value).Reverse().ToArray();
А>>> }
А>>>}

S>>*) записи не упорядоченны и берутся не последние

А>записи как раз упорядочены по Index в порядке добавления, допустим index текущий = 5000, соотвественно запрос выберет с 5001-10000 и сделает union с 1-5000 записи — получится список в хронологическом порядке — ему делается reverse().

Это тоже вызывает сомнение. В этом коде Вы зачем-то перекопируете кусок списка, причём как-то даже нечитабельно.

Мне кажется, Вы можете хранить список так, чтобы отрезать приходилось с начала и использовать энумератор. Причём я бы тупо складывал по одному элементу в заранее заведённый массив. В Вашем коде, сдаётся мне, происходит несколько дублирующих операций.
Re[6]: Очередь фиксированного размера с вытеснением старых
От: samius Япония http://sams-tricks.blogspot.com
Дата: 19.01.11 09:33
Оценка:
Здравствуйте, SanyaVB, Вы писали:

SVB>Здравствуйте, Аноним, Вы писали:


А>>>>Не совсем то. Ниже тестовый пример, может я неправильно с ней работаю.

А>>>>Dequene будет съедать элемент, и второму потоку оно не достанется. самое старое значение должно вытесняться при вставке нового элемента а не при чтении.
Да, кстати, что по выделенному (вопрос к ТС-у). RemoveAt у списка тоже съедает элемент, и он тоже не достанется другим потокам...

SVB>А зачем работать напильником? Можно самому написать класс, который будет отвечать этим требованиям. Если емкость очереди задается, то чтобы не тратить время на удаление, можно выделить сразу нужную память и просто при необходимости перезаписывать элементы массива. Вот набросок:


SVB>
SVB>    class LimitedQueue 
SVB>    {
SVB>    }
SVB>

Все это кроме индексированного доступа предоставляет Queue из коробки.

SVB>Можно также наследоваться от IEnumerable и уже здесь сделать потокобезопасность

Как именно, кроме блокирования всей структуры во время записи/перебора?

SVB>Или задача состоит в том, чтобы использовать уже готовые списки

А свой чем лучше?
Re[4]: Очередь фиксированного размера с вытеснением старых
От: samius Япония http://sams-tricks.blogspot.com
Дата: 19.01.11 09:37
Оценка:
Здравствуйте, dims12, Вы писали:

D>Здравствуйте, Аноним, Вы писали:


А>>Вполне шустро работает. Меньше миллисекунды..196 тиков всего.

А>>А он не двигает все элементы при удаленни чтоли ?

D>Ну он как-то блоками работает. Заводится блок, скажем, длиной 100 позиций, в нём помнится, где конец и где начало. При удалении с головы сдвигается указатель на начало, при добавлении в хвост -- на конец. Если элементов становится больше, то происходит реорганизация. Я думаю как-то так. В любом случае, это внутренняя кухня.

Это не о List<T>.
D>Мы должны руководствоваться мануалом:

D>If Count is less than Capacity, this method is an O(1) operation. If the capacity needs to be increased to accommodate the new element, this method becomes an O(n) operation, where n is Count.

Речь о сложности операции удаления, а List<T> при удалении элемента передвигает весь хвост, а значит сложность O(n).
Re[5]: Очередь фиксированного размера с вытеснением старых
От: dims12 http://www.relativity.ru
Дата: 19.01.11 09:44
Оценка:
Здравствуйте, samius, Вы писали:

D>>If Count is less than Capacity, this method is an O(1) operation. If the capacity needs to be increased to accommodate the new element, this method becomes an O(n) operation, where n is Count.

S>Речь о сложности операции удаления, а List<T> при удалении элемента передвигает весь хвост, а значит сложность O(n).

Да, Вы правы.
Re[7]: Очередь фиксированного размера с вытеснением старых
От: SanyaVB  
Дата: 19.01.11 11:03
Оценка:
Здравствуйте, samius, Вы писали:

S>Здравствуйте, SanyaVB, Вы писали:


SVB>>Здравствуйте, Аноним, Вы писали:



S>Все это кроме индексированного доступа предоставляет Queue из коробки.


Не знал что Queue имеет ограничение по элементам
Емкость коллекции Queue — это количество элементов, которое может вместить коллекция Queue. Когда в коллекцию Queue добавляются элементы, ее емкость автоматически увеличивается должным образом посредством перераспределения.

SVB>>Можно также наследоваться от IEnumerable и уже здесь сделать потокобезопасность

S>Как именно, кроме блокирования всей структуры во время записи/перебора?
Можно залочить статическую переменную... вообщем все зависит от того где применяется эта очередь. Но это уже вопрос по другой теме

SVB>>Или задача состоит в том, чтобы использовать уже готовые списки

S>А свой чем лучше?
человек хочет ограничить емкость и при добавлении нового элемента затирать старый, если очередь вся заполнилась. Конечно мы можем использовать такие методы как Enqueue() и Dequeue() чтобы получить ожидаемое. Кстати Dequeue() возвращает элемент, котором в этом случае использовать нет смысла(когда нет смысла — меня коробит ), т.к. задача удалить элемент И так! мы удаляем элемент, а потом добавляем элемент. В моем случае мы только добавляем элементы и затираем старые. но возможно Queue при изъятия элемента его не удаляет, а просто теряется возможность обратиться к этому элементу. Вот только лень лезть в Reflector
Re[8]: Очередь фиксированного размера с вытеснением старых
От: samius Япония http://sams-tricks.blogspot.com
Дата: 19.01.11 11:17
Оценка:
Здравствуйте, SanyaVB, Вы писали:

SVB>Здравствуйте, samius, Вы писали:


S>>Здравствуйте, SanyaVB, Вы писали:


SVB>>>Здравствуйте, Аноним, Вы писали:



S>>Все это кроме индексированного доступа предоставляет Queue из коробки.


SVB>Не знал что Queue имеет ограничение по элементам

Отсутстввие такого ограничения это проблема, ради которой нужно мопедировать свой контейнер?

SVB>Емкость коллекции Queue — это количество элементов, которое может вместить коллекция Queue. Когда в коллекцию Queue добавляются элементы, ее емкость автоматически увеличивается должным образом посредством перераспределения.

Выглядит как вступление к некому умозаключению, но вот заключения нет...

SVB>>>Можно также наследоваться от IEnumerable и уже здесь сделать потокобезопасность

S>>Как именно, кроме блокирования всей структуры во время записи/перебора?
SVB>Можно залочить статическую переменную... вообщем все зависит от того где применяется эта очередь. Но это уже вопрос по другой теме
Можно, но это уже походит на блокировку не одной очереди, а всех очередей в домене

SVB>>>Или задача состоит в том, чтобы использовать уже готовые списки

S>>А свой чем лучше?
SVB>человек хочет ограничить емкость и при добавлении нового элемента затирать старый, если очередь вся заполнилась. Конечно мы можем использовать такие методы как Enqueue() и Dequeue() чтобы получить ожидаемое. Кстати Dequeue() возвращает элемент, котором в этом случае использовать нет смысла(когда нет смысла — меня коробит ), т.к. задача удалить элемент И так! мы удаляем элемент, а потом добавляем элемент. В моем случае мы только добавляем элементы и затираем старые. но возможно Queue при изъятия элемента его не удаляет, а просто теряется возможность обратиться к этому элементу. Вот только лень лезть в Reflector
Ради того что бы получить метод, не возвращающий элемент при удалении писать свой контейнер?
Re[9]: Очередь фиксированного размера с вытеснением старых
От: SanyaVB  
Дата: 19.01.11 11:31
Оценка:
Здравствуйте, samius, Вы писали:

S>Здравствуйте, SanyaVB, Вы писали:


SVB>>Здравствуйте, samius, Вы писали:


S>>>Здравствуйте, SanyaVB, Вы писали:


SVB>>>>Здравствуйте, Аноним, Вы писали:


S>Ради того что бы получить метод, не возвращающий элемент при удалении писать свой контейнер?

Контейнер все равно придется писать, даже если он будет использовать Queue — теория чистого кода
Поэтому кто как хочет. по строчкам кода не большое различие...
Re[10]: Очередь фиксированного размера с вытеснением старых
От: samius Япония http://sams-tricks.blogspot.com
Дата: 19.01.11 11:33
Оценка:
Здравствуйте, SanyaVB, Вы писали:

SVB>Здравствуйте, samius, Вы писали:


S>>Ради того что бы получить метод, не возвращающий элемент при удалении писать свой контейнер?

SVB>Контейнер все равно придется писать, даже если он будет использовать Queue — теория чистого кода
Что за теория такая?

SVB>Поэтому кто как хочет. по строчкам кода не большое различие...

между тем писать свой или нет? Я так не считаю.
Re[11]: Очередь фиксированного размера с вытеснением старых
От: SanyaVB  
Дата: 19.01.11 11:45
Оценка:
Здравствуйте, samius, Вы писали:

S>Здравствуйте, SanyaVB, Вы писали:


SVB>>Здравствуйте, samius, Вы писали:


S>>>Ради того что бы получить метод, не возвращающий элемент при удалении писать свой контейнер?

SVB>>Контейнер все равно придется писать, даже если он будет использовать Queue — теория чистого кода
S>Что за теория такая?
чистый код

SVB>>Поэтому кто как хочет. по строчкам кода не большое различие...

S>между тем писать свой или нет? Я так не считаю.
Может быть, может быть... но если контейнер свой делать то придется скорее всего наследовать его от IEnumerable<T>, IEnumerator<T>. Тут больше строчек уйдет на фигурные скобочки и названия методов...
Re[12]: Очередь фиксированного размера с вытеснением старых
От: samius Япония http://sams-tricks.blogspot.com
Дата: 19.01.11 11:52
Оценка:
Здравствуйте, SanyaVB, Вы писали:

SVB>Здравствуйте, samius, Вы писали:


S>>Здравствуйте, SanyaVB, Вы писали:


SVB>>>Здравствуйте, samius, Вы писали:


S>>>>Ради того что бы получить метод, не возвращающий элемент при удалении писать свой контейнер?

SVB>>>Контейнер все равно придется писать, даже если он будет использовать Queue — теория чистого кода
S>>Что за теория такая?
SVB>чистый код
Я не понимаю. Ты предлагаешь не использовать очередь потому как Dequeue возвращает элемент, и отсылаешь к Бобу Мартину за объяснениями? Давай конкретнее, главу, страницу и т.п.

SVB>>>Поэтому кто как хочет. по строчкам кода не большое различие...

S>>между тем писать свой или нет? Я так не считаю.
SVB>Может быть, может быть... но если контейнер свой делать то придется скорее всего наследовать его от IEnumerable<T>, IEnumerator<T>. Тут больше строчек уйдет на фигурные скобочки и названия методов...
А ради чего собственно свой-то?
Re[13]: Очередь фиксированного размера с вытеснением старых
От: SanyaVB  
Дата: 19.01.11 12:08
Оценка:
Здравствуйте, samius, Вы писали:

S>Здравствуйте, SanyaVB, Вы писали:


SVB>>Здравствуйте, samius, Вы писали:


S>>>Здравствуйте, SanyaVB, Вы писали:


SVB>>>>Здравствуйте, samius, Вы писали:



S>Я не понимаю. Ты предлагаешь не использовать очередь потому как Dequeue возвращает элемент, и отсылаешь к Бобу Мартину за объяснениями? Давай конкретнее, главу, страницу и т.п.


Конечно не из-за этого. Задача контейнера Queue немного отличается от поставленной задачи => нужно делать обертку в результате которой получаем контейнер для поставленной задачи. Такой код хорошо читаем. Мы знаем что этот контейнер отвечает таким требованиям и у него есть метод Add(...) и при необходимости можем прогнать по циклу.
PS: Была бы у меня книга под рукой — написал бы номер глав, но как припоминается с первой по последнюю про это говорится, т.к. учат писать так, чтобы легко можно было код без комментариев прочитать
Я не говорю что твой вариант неверный. кто-то вообще переменные называют a,b,c,d...
Re[14]: Очередь фиксированного размера с вытеснением старых
От: samius Япония http://sams-tricks.blogspot.com
Дата: 19.01.11 12:20
Оценка:
Здравствуйте, SanyaVB, Вы писали:

SVB>Здравствуйте, samius, Вы писали:


S>>Я не понимаю. Ты предлагаешь не использовать очередь потому как Dequeue возвращает элемент, и отсылаешь к Бобу Мартину за объяснениями? Давай конкретнее, главу, страницу и т.п.


SVB>Конечно не из-за этого. Задача контейнера Queue немного отличается от поставленной задачи => нужно делать обертку в результате которой получаем контейнер для поставленной задачи.

Про обертку очень неочевидный переход. Вообще необходимость спецконтейнера под вопросом.

SVB>Такой код хорошо читаем. Мы знаем что этот контейнер отвечает таким требованиям и у него есть метод Add(...) и при необходимости можем прогнать по циклу.

Код мопедного контейнера лучше читаем чем код использования стандартного?

SVB>PS: Была бы у меня книга под рукой — написал бы номер глав, но как припоминается с первой по последнюю про это говорится, т.к. учат писать так, чтобы легко можно было код без комментариев прочитать

Про то что учат что бы код можно было легко читать без комментариев — это верно. Но необходимость самописного контейнера для такой задачи из этого не вытекает.
Давай по-другому. Представим что такой контейнер написан. Откуда по-твоему читающий код должен понять, нафига этот контейнер нужен? (особенно без комментариев)

SVB>Я не говорю что твой вариант неверный. кто-то вообще переменные называют a,b,c,d...

Угу, а кто-то мопедирует контейнеры что бы чего лишнего не вернули.
Re[15]: Очередь фиксированного размера с вытеснением старых
От: SanyaVB  
Дата: 19.01.11 12:46
Оценка:
Здравствуйте, samius, Вы писали:

S>Здравствуйте, SanyaVB, Вы писали:


SVB>>Здравствуйте, samius, Вы писали:



S>Давай по-другому. Представим что такой контейнер написан. Откуда по-твоему читающий код должен понять, нафига этот контейнер нужен? (особенно без комментариев)


Из названия конечно. Только не спрашивай у меня как я его назову

Комментарии по той или другой причине в основном ЛГУТ, т.к. код и логика меняется, а комментарии остаются... Я не против комментариев, но я их избегаю.

Пойми, если эту реализацию нужно использовать в нескольких местах, то желательно сделать обертку. Ты то ладно... поймешь через месяца два что ты написал(раз у тебя в крови это), а другой человек? какое то Dequeue и Enqueue???? зачем??? ааа!!! точно — это реализация ограничения! А если есть обертка, то из название понятно что очередь(список или стек) фиксирована. Интересно как? заходим и смотрим: все ясно с помощью Dequeue и Enqueue.... Дальше надо объяснять?
Re[16]: Очередь фиксированного размера с вытеснением старых
От: samius Япония http://sams-tricks.blogspot.com
Дата: 19.01.11 13:19
Оценка:
Здравствуйте, SanyaVB, Вы писали:

SVB>Здравствуйте, samius, Вы писали:


S>>Давай по-другому. Представим что такой контейнер написан. Откуда по-твоему читающий код должен понять, нафига этот контейнер нужен? (особенно без комментариев)


SVB>Из названия конечно. Только не спрашивай у меня как я его назову


SVB>Комментарии по той или другой причине в основном ЛГУТ, т.к. код и логика меняется, а комментарии остаются... Я не против комментариев, но я их избегаю.


SVB>Пойми, если эту реализацию нужно использовать в нескольких местах, то желательно сделать обертку.

Вообще-то ты начал со своего контейнера, а потом переключился на обертку. Обертка — фиг с ней, пусть обертка.

SVB>Ты то ладно... поймешь через месяца два что ты написал(раз у тебя в крови это), а другой человек? какое то Dequeue и Enqueue???? зачем??? ааа!!! точно — это реализация ограничения! А если есть обертка, то из название понятно что очередь(список или стек) фиксирована. Интересно как? заходим и смотрим: все ясно с помощью Dequeue и Enqueue....

Сначала мотивацией к написанию контейнера было то что Dequeue возвращает значение, которое не нужно. Именно по этому поводу ты отослал к Бобу М. В случае обертки разве это не страшно?
Теперь то что методы Dequeue и Enqueue надо вызывать и что кто-то не поймет для чего...
Ладно, пусть реюз. Но почему бы не ограничиться написанием метода, который вызовет Dequeue и Enqueue? Зачем городить обертки и протягивать им IEnumerable, ToArray, Count и т.п.?

SVB>Дальше надо объяснять?

Конечно
Re[8]: Очередь фиксированного размера с вытеснением старых
От: _d_m_  
Дата: 19.01.11 15:08
Оценка:
Здравствуйте, SanyaVB, Вы писали:

SVB>человек хочет ограничить емкость и при добавлении нового элемента затирать старый, если очередь вся заполнилась. Конечно мы можем использовать такие методы как Enqueue() и Dequeue() чтобы получить ожидаемое. Кстати Dequeue() возвращает элемент, котором в этом случае использовать нет смысла(когда нет смысла — меня коробит ), т.к. задача удалить элемент


Детский сад.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.