Re[7]: Создание эффективного контейнера для работы со списко
От: alsemm Россия  
Дата: 18.06.04 15:13
Оценка:
Здравствуйте, Serginio1, Вы писали:

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


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


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


A>>>Ты в http://www.rsdn.ru/Forum/Message.aspx?mid=525083&only=1
Автор: Сергей Смирнов (Serginio1)
Дата: 30.01.04
писал про сортированный список, тут другой случай:

A>>>обход элементов осуществляется в том же порядке, в каком они были добавлены в контейнер. В этом фишка

S>> Так в массивы они добавляются именно в ту позицию в которую ты хочешь. Просто в Б+ деревьях эта позиция определяется бинарным поиском,

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

S>>
S>>     public class seg<T>
S>>      {
S>>        T PageItems[n]; // например n =64;
S>>        int Count;
S>        seg<T>> Parent;
S>        seg<T>> Left;
S>        seg<T>> Right;
S>>        }
S>>


S>> Находишь позицию куда вставить раздвигаешь массив и вставляешь элемент в нужную позицию.

S>> Если массив полностью заполнен перекидываешь элементы вправо или влево или выделяешь новый сенмент. и перекидываешь половину элементов.

S> Только прошу прощения в твоем варианте должна быть такого плана


S> public class seg<T>

S> {
S> T PageItems[n]; // например n =64;
S> int Count;
S> seg<T>> Parent;
S> seg<T>> ChildLeft;
S> seg<T>> ChildRight;
S> seg<T>> Prior; // указатель на следующий сегмент
S> seg<T>> Next; // указатель на следующий сегмент
S> }

S> Я думаю так понятней будет. И соответственно проход быстрый.


Ага.
Re[9]: Создание эффективного контейнера для работы со списко
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 18.06.04 15:16
Оценка:
Здравствуйте, alsemm, Вы писали:

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


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




S>>>> Так в массивы они добавляются именно в ту позицию в которую ты хочешь. Просто в Б+ деревьях эта позиция определяется бинарным поиском,

S>>>> у тебя иначе, но сами структуры данных близки.
A>>>Так и у меня бинарным поиском позиция ищется. Потом правда приходится немного по мписку пройтись, чтобы точно позицию получить.
S>> Вот про это то я как раз и говорю.
A>Да, есть там такая мерзость.

S>> Кстати добавил бы тест на поиск массиве рассортированных IDX на запоненном slist и list в полном диапозоне. При не попадании в кэш поиск твоим методом должен сильно тормозится.

A>На словах непонятно, псевдокод приведи чего сравнивать.

S>> И оценить время на построение дерева.

A>Согласен, лишним не будет.


Делаем процедуру рперемешивания

 public void unsortarray(Int32[] OrigArray)
        {
            Int32 j, k, tempbuff;
            Random r = new Random(666666);

            for (Int32 i = 0; i < OrigArray.Length; i++)
            {
                j = r.Next(OrigArray.Length - 1);
                k = r.Next(OrigArray.Length - 1);
                tempbuff = OrigArray[j];
                OrigArray[j] = OrigArray[k];
                OrigArray[k] = tempbuff;
            }
        }



Заполняем slist Затем получаем массив n элементов
 for (Int32 ii = 0; ii < OrigArray.Length; ii++)
            {
                OrigArray[ii] = ii;
            }


рассортировываем
unsortarray(OrigArray);


А затем производим поиск
        timer.Start();
            for (Int32 ii = 0; ii < OrigArray.Length; ii++)
            {
                if (!BT.NavigateKey(OrigArray[ii]))
                {
                    textBox1.AppendText("i=" + ii.ToString() + " Не найден " 
                        + OrigArray[ii].ToString() + "]\r\n");
                    break;
                }
            }

            TimeRunning = timer.Finish();
            textBox1.AppendText("Поиск в Btree " + TimeRunning.ToString() + "\r\n");
... << RSDN@Home 1.1.0 stable >>
и солнце б утром не вставало, когда бы не было меня
Re[10]: Создание эффективного контейнера для работы со списк
От: alsemm Россия  
Дата: 18.06.04 15:39
Оценка:
Здравствуйте, Serginio1, Вы писали:

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


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


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




S>>>>> Так в массивы они добавляются именно в ту позицию в которую ты хочешь. Просто в Б+ деревьях эта позиция определяется бинарным поиском,

S>>>>> у тебя иначе, но сами структуры данных близки.
A>>>>Так и у меня бинарным поиском позиция ищется. Потом правда приходится немного по мписку пройтись, чтобы точно позицию получить.
S>>> Вот про это то я как раз и говорю.
A>>Да, есть там такая мерзость.

S>>> Кстати добавил бы тест на поиск массиве рассортированных IDX на запоненном slist и list в полном диапозоне. При не попадании в кэш поиск твоим методом должен сильно тормозится.

A>>На словах непонятно, псевдокод приведи чего сравнивать.

S>>> И оценить время на построение дерева.

A>>Согласен, лишним не будет.


S> Делаем процедуру рперемешивания


S>
S> public void unsortarray(Int32[] OrigArray)
S>        {
S>            Int32 j, k, tempbuff;
S>            Random r = new Random(666666);

S>            for (Int32 i = 0; i < OrigArray.Length; i++)
S>            {
S>                j = r.Next(OrigArray.Length - 1);
S>                k = r.Next(OrigArray.Length - 1);
S>                tempbuff = OrigArray[j];
S>                OrigArray[j] = OrigArray[k];
S>                OrigArray[k] = tempbuff;
S>            }
S>        }

S>



S> Заполняем slist Затем получаем массив n элементов

S>
S> for (Int32 ii = 0; ii < OrigArray.Length; ii++)
S>            {
S>                OrigArray[ii] = ii;
S>            }
S>


S> рассортировываем

S>unsortarray(OrigArray);


S> А затем производим поиск

S>
S>        timer.Start();
S>            for (Int32 ii = 0; ii < OrigArray.Length; ii++)
S>            {
S>                if (!BT.NavigateKey(OrigArray[ii]))
S>                {
S>                    textBox1.AppendText("i=" + ii.ToString() + " Не найден " 
S>                        + OrigArray[ii].ToString() + "]\r\n");
S>                    break;
S>                }
S>            }

S>            TimeRunning = timer.Finish();
S>            textBox1.AppendText("Поиск в Btree " + TimeRunning.ToString() + "\r\n"); 

S>

Идея ясна.

Тут сравнивай не сравнивай, slist будет точно лучше list-а, вопрос только на сколько. Хотя тест написать недолго
Re[11]: Создание эффективного контейнера для работы со списк
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 18.06.04 15:53
Оценка:
Здравствуйте, alsemm, Вы писали:


A>Идея ясна.


A>Тут сравнивай не сравнивай, slist будет точно лучше list-а, вопрос только на сколько. Хотя тест написать недолго


Ну и сравнить разные реализации slist.
Кроме того можно оценить поисковую состовляющую при вставке. Хотя и приблизительно но порядок будет верным.
... << RSDN@Home 1.1.0 stable >>
и солнце б утром не вставало, когда бы не было меня
Re[12]: Создание эффективного контейнера для работы со списк
От: alsemm Россия  
Дата: 18.06.04 15:57
Оценка:
Здравствуйте, Serginio1, Вы писали:

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



A>>Идея ясна.


A>>Тут сравнивай не сравнивай, slist будет точно лучше list-а, вопрос только на сколько. Хотя тест написать недолго


S> Ну и сравнить разные реализации slist.

S> Кроме того можно оценить поисковую состовляющую при вставке. Хотя и приблизительно но порядок будет верным.
Это уже на вторую часть статьи тянет
Re[13]: Создание эффективного контейнера для работы со списк
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 18.06.04 16:12
Оценка:
Здравствуйте, alsemm, Вы писали:


A>>>Тут сравнивай не сравнивай, slist будет точно лучше list-а, вопрос только на сколько. Хотя тест написать недолго


S>> Ну и сравнить разные реализации slist.

S>> Кроме того можно оценить поисковую состовляющую при вставке. Хотя и приблизительно но порядок будет верным.
A>Это уже на вторую часть статьи тянет
Ну я думаю это не так уж и сложно. Реализация на массиве будет очень близка к list (правда итераторы написать но это не долго).
Просто меня сильно цифири в таблице 5 несколько смутили. На Б+ деревьях вставка
100 000 элементов порядка 0.07 сек.
1 000 000 элементов порядка 1.4
Вот и интересно посмотреть как скажется сегмент на массивах который и применяется в Б+ деревьях.
Отличаются только алгоритмы поиска и построения дерева
... << RSDN@Home 1.1.0 stable >>
и солнце б утром не вставало, когда бы не было меня
Re: Создание эффективного контейнера для работы со списком б
От: c-smile Канада http://terrainformatica.com
Дата: 18.06.04 23:48
Оценка:
Здравствуйте, Алексей Семенюк, Вы писали:

А>Аннотация:

А>В статье приводится пример реализации нестандартного контейнера, позволяющего обеспечить приемлемую скорость доступа к произвольному элементу и вставки/удаления в произвольную позицию.

А это случайно не про sparse arrays статья ?

Ссылки по теме:
http://www.eecs.harvard.edu/~ellard/Q-97/HTML/root/node9.html
http://www.eecs.harvard.edu/~ellard/Q-97/HTML/root/node47.html
http://math.nist.gov/sparselib++/
Re[2]: Создание эффективного контейнера для работы со списко
От: alsemm Россия  
Дата: 19.06.04 06:43
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>Здравствуйте, Алексей Семенюк, Вы писали:


А>>Аннотация:

А>>В статье приводится пример реализации нестандартного контейнера, позволяющего обеспечить приемлемую скорость доступа к произвольному элементу и вставки/удаления в произвольную позицию.

CS>А это случайно не про sparse arrays статья ?

Нет, статья не про разряженные массивы

CS>Ссылки по теме:

CS>http://www.eecs.harvard.edu/~ellard/Q-97/HTML/root/node9.html
CS>http://www.eecs.harvard.edu/~ellard/Q-97/HTML/root/node47.html
CS>http://math.nist.gov/sparselib++/
Re[11]: Создание эффективного контейнера для работы со списк
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 21.06.04 10:45
Оценка:
Здравствуйте, alsemm, Вы писали:

A>Тут сравнивай не сравнивай, slist будет точно лучше list-а, вопрос только на сколько. Хотя тест написать недолго

Ну увеличить скорость list и так достаточно просто

Напишу на C# такой класс.


      public class Page<T>
      {
        T PageItems[n]; // например n =64;
        int Count;
        ListArray<T> Owner;
        seg<T>> LeftPage;
        seg<T>> RightPage;
        }


      public clscc ListArray<T>
         {
            internal Page<T>  CurrentPage;  // Текущая страница с данными
                internal Page<T>  FirstPage;
                internal Page<T>  LastPage;
              internal int _currentElementIndex; // Текущий индекс элемента в массиве 
            internal int _count;   // Количество элементов в объекте
   
       public Find(int idx)
         {
           if (idx<_count/2)
             {
               int k=idx;
                 CurrentPage=FirstPage;
                  
                    while (k>=CurrentPage.Count) 
                    {
                    k-=CurrentPage.Count;
                    CurrentPage=CurrentPage.RightPage;
                }
                    _currentElementIndex=k;
                    
             }
             else
             {
             int k=_count-idx;
                 CurrentPage=LastPage;
                  
                    while (k>CurrentPage.Count) 
                    {
                    k-=CurrentPage.Count;
                    CurrentPage=CurrentPage.LeftPage;
                }
                    _currentElementIndex=CurrentPage.Count-k;
             
             }
             }
         
         
         }
}


И соответственно вставку и удаление возму из своей TwoLevelSortedDictonary<K,V>
думаю будет понятно

private void Insert(K Key)
        {
            // Раздвигаем массив с текущей позиции, и вставляем ключ
            Array.Copy(CurrentLeafPage.PageItems, _currentElementIndex, CurrentLeafPage.PageItems,
            _currentElementIndex + 1, CurrentLeafPage.Count - _currentElementIndex);
            CurrentLeafPage.Count++;
            CurrentLeafPage.PageItems[_currentElementIndex].Key = Key;
            // Произошли изменения увеличиваем текущую версию
            version++;
            _count++;

            // Проверка на полное заполнение массива
            if (CurrentLeafPage.Count == BTConst.MaxCount)
            {
                // Проверка на существование второго уровня
                if (_pageCount == 1)
                {

                    // Второго уровня еще нет. Аналогичная операция и в Б+ деревьях
                    //Делим текущую страницу пополам

                    LeafPage<K,V> NewPage = new LeafPage<K,V>();
                    // Устанавливаем нужные ссылки в полях NextPage и PriorPage
                    CurrentLeafPage.NextPage = NewPage;
                    NewPage.PriorPage = CurrentLeafPage;

                    // Копируем половину данных из исходного массива в новый выделенный
                    Array.Copy(CurrentLeafPage.PageItems, BTConst.MidlCount, NewPage.PageItems, 0, BTConst.MidlCount);

                    // Очищаем освободившееся пространство
                    Array.Clear(CurrentLeafPage.PageItems, BTConst.MidlCount, BTConst.MidlCount);

                    // Создаем массив второго уровня и устанавливаем первые два его значения
                    NodeArray = new NodeItem[BTConst.MaxCount];
                    _pageCount = 2;
                    NodeArray[0].Key = CurrentLeafPage.PageItems[0].Key;
                    NodeArray[0].ChildPage = CurrentLeafPage;
                    NodeArray[1].Key = NewPage.PageItems[0].Key;
                    NodeArray[1].ChildPage = NewPage;

                    // Устанавливаем новое количество элементов на страницах
                    CurrentLeafPage.Count = BTConst.MidlCount;
                    NewPage.Count = BTConst.MidlCount;

                    // Проверяем новую текущую позицию вставленного элемента
                    if (_currentElementIndex >= BTConst.MidlCount)
                    {
                        CurrentLeafPage = NewPage;
                        _currentElementIndex -= BTConst.MidlCount;
                    }
                }
                else
                {
    // Второй уровень уж существует. Попробуем перекинуть значения в влизлежащие страницы.
    // Это не столь критично для вставки как при удалении, но есть варианты при вставке 
    //последовательных данных, когда страницы будут заполнены только на половину
    // Но для того, что бы не перекидывать по малому количеству элементов желательно, что бы //соседняя страница  была заполнена менее ?+1 емкости страницы

                    LeafPage<K,V> LeftPage = CurrentLeafPage.PriorPage;

                    if (LeftPage != null)
                    {
                        if (LeftPage.Count <= BTConst.MaxFill)
                        {
// можно перекинуть значения на левую страницу находим нужное количесво
// элементов для переброски

                            int MoveCount = (BTConst.MaxCount - LeftPage.Count) / 2;
// Копируем начальные элементы из текущей страницы в конец левой страницы
                            Array.Copy(CurrentLeafPage.PageItems, 0, LeftPage.PageItems, LeftPage.Count, MoveCount);
// Копируем оставшиеся элементы текущей страницы в начало
                            Array.Copy(CurrentLeafPage.PageItems, MoveCount, CurrentLeafPage.PageItems, 0, CurrentLeafPage.Count - MoveCount);
// Очищаем освободившееся место в текущем массиве
                            Array.Clear(CurrentLeafPage.PageItems, CurrentLeafPage.Count - MoveCount, MoveCount);

// Устанавливаем новое значение ключа в текущую позицию NodeArray

                            NodeArray[_currentPageIndex].Key = CurrentLeafPage.PageItems[0].Key;

// Проверяем новую текущую позицию вставленного элемента
                            if (_currentElementIndex < MoveCount)
                            {
                                _currentElementIndex += LeftPage.Count;
                                CurrentLeafPage.Count -= MoveCount;
                                LeftPage.Count += MoveCount;
                                CurrentLeafPage = LeftPage;
                            }
                            else
                            {
                                _currentElementIndex -= MoveCount;
                                CurrentLeafPage.Count -= MoveCount;
                                LeftPage.Count += MoveCount;
                                
                            }

                            return;
                        }
                    }
                    // С левой страницей не получилось попробуем с правой
                    LeafPage<K,V> RightPage = CurrentLeafPage.NextPage;

                    if (RightPage != null)
                    {
                        if (RightPage.Count <= BTConst.MaxFill)
                        {
                            int MoveCount = (BTConst.MaxCount - RightPage.Count) / 2;

                            Array.Copy(RightPage.PageItems, 0, RightPage.PageItems, MoveCount, RightPage.Count);
                            Array.Copy(CurrentLeafPage.PageItems, BTConst.MaxCount - MoveCount, 
                            RightPage.PageItems, 0, MoveCount);
                            Array.Clear(CurrentLeafPage.PageItems, CurrentLeafPage.Count - MoveCount, MoveCount);
                            NodeArray[_currentPageIndex + 1].Key = RightPage.PageItems[0].Key;
                            CurrentLeafPage.Count -= MoveCount;
                            RightPage.Count += MoveCount;
                            if (_currentElementIndex >= CurrentLeafPage.Count)
                            {
                                _currentElementIndex -= CurrentLeafPage.Count;
                                CurrentLeafPage = RightPage;
                            }

                            return;
                        }
                    }

                    // Не получилось сбалансировать ну и ....
                    // Выделяемновую страницу и вставляем в NodeArray;
                    LeafPage<K,V> NewPage = new LeafPage<K,V>();
    // Устанавливаем нужные ссылки в полях NextPage и PriorPage
                    NewPage.NextPage = CurrentLeafPage.NextPage;
                    NewPage.PriorPage = CurrentLeafPage;
                    CurrentLeafPage.NextPage = NewPage;
                    if (NewPage.NextPage != null)
                        NewPage.NextPage.PriorPage = NewPage;

                    // Действия аналогичные при выделения второго уровня
                    Array.Copy(CurrentLeafPage.PageItems, BTConst.MidlCount, NewPage.PageItems, 0, BTConst.MidlCount);
                    Array.Clear(CurrentLeafPage.PageItems, BTConst.MidlCount, BTConst.MidlCount);
                    Array.Copy(NodeArray, _currentPageIndex + 1, NodeArray, _currentPageIndex + 2, _pageCount - _currentPageIndex - 1);
                    NodeArray[_currentPageIndex + 1].Key = NewPage.PageItems[0].Key;
                    NodeArray[_currentPageIndex + 1].ChildPage = NewPage;
                    CurrentLeafPage.Count = BTConst.MidlCount;
                    NewPage.Count = BTConst.MidlCount;
         
                    // Проверяем текущую позицию вставляемого элемента    
                    if (_currentElementIndex >= BTConst.MidlCount)
                    {
                        CurrentLeafPage = NewPage;
                        _currentElementIndex -= BTConst.MidlCount;
                    }
                    _pageCount++;

                    //Проверяем вариант на полное заполнение NodeArray.
                    // Если заполненили полностью, то просто увеличиваем его в 2 раза
                    // В Б+ деревьях в этом случае выстраивается новый уровень

                    if (_pageCount == NodeArray.Length)
                    {
                        NodeItem[] NewNodeArray = new NodeItem[2 * _pageCount];

                        Array.Copy(NodeArray, 0, NewNodeArray, 0, _pageCount);
                        NodeArray = NewNodeArray;
                    }
                }
            }
        }


В отличие от сишного memmove в ArrayCopy идет источник затем потребитель.

И соответственно удаление

         /// Процедура удаления текущего элемента. При этом
        ///позиция верхнего уровня должна укпзыватьна текущую страницу
        /// </summary>
        private void Delete()
        {
            CurrentLeafPage.Count--;
            if (_currentElementIndex < CurrentLeafPage.Count)
            {
                Array.Copy(CurrentLeafPage.PageItems, _currentElementIndex + 1, CurrentLeafPage.PageItems, _currentElementIndex, CurrentLeafPage.Count - _currentElementIndex);
            }

            // Увеличиваем текущую верстю
            version++;
            
            // Очищаем освободившееся место
            CurrentLeafPage.PageItems[CurrentLeafPage.Count] = KeyValuePair<K,V>.default;
            
            //  Проверим на удаление нулевого элемента, т.к. копия его ключа
            // хранится в родительском массиве
            if ((_currentElementIndex == 0) && (_pageCount>1))
            {
                NodeArray[this._currentPageIndex].Key = CurrentLeafPage.PageItems[0].Key;
            }

            // Проверим новой количество элементов на странице и если их количество
            // стало меньше половины емкости страницы займем их у ближайших страниц
            if ((CurrentLeafPage.Count < BTConst.MidlCount) && (_pageCount > 0))
            {
                LeafPage<K,V> LeftPage = CurrentLeafPage.PriorPage;
                // попробуем занять у левой страницы
                if (LeftPage != null)
                {
                    if ((LeftPage.Count + CurrentLeafPage.Count) <= BTConst.MaxCount)
                    {
                        // Вариант когда из двух страниц делаем одну
                        // Всегда перекидываем в левую страницу

                        Array.Copy(CurrentLeafPage.PageItems, 0, LeftPage.PageItems, LeftPage.Count, CurrentLeafPage.Count);
                        LeftPage.NextPage = CurrentLeafPage.NextPage;
                        
                        if (CurrentLeafPage.NextPage!=null)
                        CurrentLeafPage.NextPage.PriorPage = LeftPage;
// Устанавливаем новый текущий индекс
                        _currentElementIndex += LeftPage.Count;
// Устанавливаем новое количество элементов на странице
                        LeftPage.Count += CurrentLeafPage.Count;
                        CurrentLeafPage = LeftPage;
                        // Удаляем ссылку на текущую страницу из NodeArray
                        DeleteNodeItem(_currentPageIndex);
                        CheckLastPositionAeterDelete();
                        return;
                    }
                    // Следующие варианты аналогичны при переброске элементов при вставке
                    int MoveCount = (LeftPage.Count - CurrentLeafPage.Count) / 2;

                    Array.Copy(CurrentLeafPage.PageItems, 0, CurrentLeafPage.PageItems, MoveCount, CurrentLeafPage.Count);
                    Array.Copy(LeftPage.PageItems, LeftPage.Count - MoveCount, CurrentLeafPage.PageItems, 0, MoveCount);
                    Array.Clear(LeftPage.PageItems, LeftPage.Count - MoveCount, MoveCount);
                    NodeArray[_currentPageIndex].Key = CurrentLeafPage.PageItems[0].Key;
                    _currentElementIndex += MoveCount;
                    LeftPage.Count -= MoveCount;
                    CurrentLeafPage.Count += MoveCount;
                    CheckLastPositionAeterDelete();
                    return;
                }

                LeafPage<K,V> RightPage = CurrentLeafPage.NextPage;

                if (RightPage != null)
                {
                    if ((RightPage.Count + CurrentLeafPage.Count) <= BTConst.MaxCount)
                    {
                        Array.Copy(RightPage.PageItems, 0, CurrentLeafPage.PageItems, CurrentLeafPage.Count, RightPage.Count);
                        CurrentLeafPage.NextPage = RightPage.NextPage;
                        
                        if (RightPage.NextPage!=null)
                        RightPage.NextPage.PriorPage = CurrentLeafPage;

                        CurrentLeafPage.Count += RightPage.Count;
                        DeleteNodeItem(_currentPageIndex + 1);
                         
                        return;
                    }

                    int MoveCount = (RightPage.Count - CurrentLeafPage.Count) / 2;

                    Array.Copy(RightPage.PageItems, 0, CurrentLeafPage.PageItems, CurrentLeafPage.Count, MoveCount);
                    Array.Copy(RightPage.PageItems, MoveCount, RightPage.PageItems, 0, RightPage.Count - MoveCount);
                    Array.Clear(RightPage.PageItems, RightPage.Count - MoveCount, MoveCount);
                    NodeArray[_currentPageIndex + 1].Key = RightPage.PageItems[0].Key;
                    CurrentLeafPage.Count += MoveCount;
                    RightPage.Count -= MoveCount;
                    return;
                }
            }
        }


Если сравнить затраты на вставку в vector и list ( к сожалению не знаю полной реализации но мои представления могут быть ошибочны, так что прошу прощения)
в vector затраты
поиск 1;
вставка N/2 * (sizeof(T)/4)(где N количество элементов)

в list
поиск N/4 (так как поиск может быть сначала или с конца)
вставка 3;

Для приведенного выше класса

поск N/k (где к средняя запоненность массива)
вставка MaxCount/2*(sizeof(T)/4) (MaxCount емкость массива на странице

Проинтегрировав по n для поиска затрат по заполнению с 0 по N в случайные позиции
Получим затрату например для интов
vector sqr(N)/4
list sqr(N)/8

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

Для приведенного выше класса

sqr(N)/8/k + N*MaxCount/2

и взяв отношение

N/(N/k+4*MaxCount)
так для 10000 это будет и при MaxCount=128 и к 100
10000/(100+ 500) = 15

а при 100000

100000/(1000+500) = 60
То есть легко можно увеличить скорость в десятки разов.
... << RSDN@Home 1.1.0 stable >>
и солнце б утром не вставало, когда бы не было меня
Re[12]: Создание эффективного контейнера для работы со списк
От: alsemm Россия  
Дата: 21.06.04 12:31
Оценка:
Здравствуйте, Serginio1, Вы писали:

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


A>>Тут сравнивай не сравнивай, slist будет точно лучше list-а, вопрос только на сколько. Хотя тест написать недолго

S> Ну увеличить скорость list и так достаточно просто

S> Напишу на C# такой класс.


кусь-кусь...

S> Если сравнить затраты на вставку в vector и list ( к сожалению не знаю полной реализации но мои представления могут быть ошибочны, так что прошу прощения)

S> в vector затраты
S> поиск 1;
S> вставка N/2 * (sizeof(T)/4)(где N количество элементов)
sizeof(T)/4 — это чего такое?
И что это за оценка для вставки: худшая или средняя? я так понимаю, что средняя.

S> в list

S> поиск N/4 (так как поиск может быть сначала или с конца)
Это в среднем, в худшем случае N/2
S> вставка 3;
Вставка для list-а всегде 1, 3-и то откуда?

S> Для приведенного выше класса


S> поск N/k (где к средняя запоненность массива)

S> вставка MaxCount/2*(sizeof(T)/4) (MaxCount емкость массива на странице

S> Проинтегрировав по n для поиска затрат по заполнению с 0 по N в случайные позиции

S> Получим затрату например для интов
S> vector sqr(N)/4
S> list sqr(N)/8
Химия какя-то, это мне непонятно

S> Данное утверждение правда сильно зависит от используемой шины памяти и самой памяти, а также попадания данных в кэш

S> т.к. даже при копировании данных не попавших в кэш для вектора будет использоваться DDR эффект в отличие от лист

S> Для приведенного выше класса


S> sqr(N)/8/k + N*MaxCount/2


S> и взяв отношение


S> N/(N/k+4*MaxCount)

S> так для 10000 это будет и при MaxCount=128 и к 100
S> 10000/(100+ 500) = 15

S> а при 100000


S> 100000/(1000+500) = 60

S> То есть легко можно увеличить скорость в десятки разов.
Насчет скорости: все выглядит очень привлекательно, надо только реализацию сделать нормальную, а не на коленке и тогда уже замеры сделать, чтобы убедиться, что расчеты верны.
Re[13]: Создание эффективного контейнера для работы со списк
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 21.06.04 12:53
Оценка:
Здравствуйте, alsemm, Вы писали:


S>> Если сравнить затраты на вставку в vector и list ( к сожалению не знаю полной реализации но мои представления могут быть ошибочны, так что прошу прощения)

S>> в vector затраты
S>> поиск 1;
S>> вставка N/2 * (sizeof(T)/4)(где N количество элементов)
A>sizeof(T)/4 — это чего такое?
A>И что это за оценка для вставки: худшая или средняя? я так понимаю, что средняя.
Берем за оценку копирования 1 инта все в среднем т.к. в задаче

S>> в list

S>> поиск N/4 (так как поиск может быть сначала или с конца)
A>Это в среднем, в худшем случае N/2
S>> вставка 3;
A>Вставка для list-а всегде 1, 3-и то откуда?
Пусть будет 1 (аставка в двухсвязнй список всетаки затрагивает левый и правй элемент, но это мелочи сказывающиеся при непопадании в кэш)

S>> Для приведенного выше класса


S>> поск N/k (где к средняя запоненность массива)

S>> вставка MaxCount/2*(sizeof(T)/4) (MaxCount емкость массива на странице

S>> Проинтегрировав по n для поиска затрат по заполнению с 0 по N в случайные позиции

S>> Получим затрату например для интов
S>> vector sqr(N)/4
S>> list sqr(N)/8
A>Химия какя-то, это мне непонятно

Ну почему, вполне согласутся с твоими данными в таблице пять хотя бы порядок.

S>> Данное утверждение правда сильно зависит от используемой шины памяти и самой памяти, а также попадания данных в кэш

S>> т.к. даже при копировании данных не попавших в кэш для вектора будет использоваться DDR эффект в отличие от лист

S>> Для приведенного выше класса


S>> sqr(N)/8/k + N*MaxCount/2


S>> и взяв отношение


S>> N/(N/k+4*MaxCount)

S>> так для 10000 это будет и при MaxCount=128 и к 100
S>> 10000/(100+ 500) = 15

S>> а при 100000


S>> 100000/(1000+500) = 60

S>> То есть легко можно увеличить скорость в десятки разов.
A>Насчет скорости: все выглядит очень привлекательно, надо только реализацию сделать нормальную, а не на коленке и тогда уже замеры сделать, чтобы убедиться, что расчеты верны.
По поводу Б+ деревьев я тебе данные приводил. И код TwoLevelSortedDictonary<K,V> Delete() и Insert() оттуда.
Кстати TwoLevelSortedDictonary<K,V> прекрасно работает до миллиона, затем резко уступает Б+ деревьям, но как промежуточный вариант очень хорошь. Твой вариант с деревом очень симпатичен, но нужно сопоставить затраты на перестроение дерева и корректировку offset.
Кстати а почему не КЧД ????
Мой вариант тоже может быть как промежуточный.
Попробуй, просто у меня нет таких задач, а писать в сол не интересно. Могу сказать, что порядок будет очень близким к теоретическим,
а то и большим если сравнивать вектор с листом на больших данных.
... << RSDN@Home 1.1.0 stable >>
и солнце б утром не вставало, когда бы не было меня
Re[14]: Создание эффективного контейнера для работы со списк
От: alsemm Россия  
Дата: 21.06.04 14:52
Оценка:
Здравствуйте, Serginio1, Вы писали:

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



S>>> Если сравнить затраты на вставку в vector и list ( к сожалению не знаю полной реализации но мои представления могут быть ошибочны, так что прошу прощения)

S>>> в vector затраты
S>>> поиск 1;
S>>> вставка N/2 * (sizeof(T)/4)(где N количество элементов)
A>>sizeof(T)/4 — это чего такое?
A>>И что это за оценка для вставки: худшая или средняя? я так понимаю, что средняя.
S> Берем за оценку копирования 1 инта все в среднем т.к. в задаче

S>>> в list

S>>> поиск N/4 (так как поиск может быть сначала или с конца)
A>>Это в среднем, в худшем случае N/2
S>>> вставка 3;
A>>Вставка для list-а всегде 1, 3-и то откуда?
S> Пусть будет 1 (аставка в двухсвязнй список всетаки затрагивает левый и правй элемент, но это мелочи сказывающиеся при непопадании в кэш)

S>>> Для приведенного выше класса


S>>> поск N/k (где к средняя запоненность массива)

S>>> вставка MaxCount/2*(sizeof(T)/4) (MaxCount емкость массива на странице

S>>> Проинтегрировав по n для поиска затрат по заполнению с 0 по N в случайные позиции

S>>> Получим затрату например для интов
S>>> vector sqr(N)/4
S>>> list sqr(N)/8
A>>Химия какя-то, это мне непонятно

S> Ну почему, вполне согласутся с твоими данными в таблице пять хотя бы порядок.

Химией я назвал sqrt, мне не понятно, как он появляется , ну да ладно.

S>>> Данное утверждение правда сильно зависит от используемой шины памяти и самой памяти, а также попадания данных в кэш

S>>> т.к. даже при копировании данных не попавших в кэш для вектора будет использоваться DDR эффект в отличие от лист

S>>> Для приведенного выше класса


S>>> sqr(N)/8/k + N*MaxCount/2


S>>> и взяв отношение


S>>> N/(N/k+4*MaxCount)

S>>> так для 10000 это будет и при MaxCount=128 и к 100
S>>> 10000/(100+ 500) = 15

S>>> а при 100000


S>>> 100000/(1000+500) = 60

S>>> То есть легко можно увеличить скорость в десятки разов.
A>>Насчет скорости: все выглядит очень привлекательно, надо только реализацию сделать нормальную, а не на коленке и тогда уже замеры сделать, чтобы убедиться, что расчеты верны.
S> По поводу Б+ деревьев я тебе данные приводил. И код TwoLevelSortedDictonary<K,V> Delete() и Insert() оттуда.
S> Кстати TwoLevelSortedDictonary<K,V> прекрасно работает до миллиона, затем резко уступает Б+ деревьям, но как промежуточный вариант очень хорошь. Твой вариант с деревом очень симпатичен, но нужно сопоставить затраты на перестроение дерева и корректировку offset.
Да, этих замеров я не делал.

S> Кстати а почему не КЧД ????

Вообщем-то из-за изъяна в образовании: когда взялся писать slist я не знал, какие есть варианты самобалансирующихся Б дреревъев (и есть-ли такие вообще), поэтому полез в google, он на запрос "self balanced tree c++" первым выдал АВЛ и 2-3 деревъевя. АВЛ показались попроще

S> Мой вариант тоже может быть как промежуточный.

S> Попробуй, просто у меня нет таких задач, а писать в сол не интересно. Могу сказать, что порядок будет очень близким к теоретическим,
S> а то и большим если сравнивать вектор с листом на больших данных.
Ок.
Re[15]: Создание эффективного контейнера для работы со списк
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 21.06.04 15:12
Оценка:
Здравствуйте, alsemm, Вы писали:


S>>>> Проинтегрировав по n для поиска затрат по заполнению с 0 по N в случайные позиции

S>>>> Получим затрату например для интов
S>>>> vector sqr(N)/4
S>>>> list sqr(N)/8
A>>>Химия какя-то, это мне непонятно

S>> Ну почему, вполне согласутся с твоими данными в таблице пять хотя бы порядок.

A>Химией я назвал sqrt, мне не понятно, как он появляется , ну да ладно.

Не знаю как в C++ в квадрате но помоему sqr (square of number) есть везде, sqrt (square root) это корень квадратны разница в t на конце
... << RSDN@Home 1.1.0 stable >>
и солнце б утром не вставало, когда бы не было меня
Re[16]: Создание эффективного контейнера для работы со списк
От: alsemm Россия  
Дата: 21.06.04 15:24
Оценка:
Здравствуйте, Serginio1, Вы писали:

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



S>>>>> Проинтегрировав по n для поиска затрат по заполнению с 0 по N в случайные позиции

S>>>>> Получим затрату например для интов
S>>>>> vector sqr(N)/4
S>>>>> list sqr(N)/8
A>>>>Химия какя-то, это мне непонятно

S>>> Ну почему, вполне согласутся с твоими данными в таблице пять хотя бы порядок.

A>>Химией я назвал sqrt, мне не понятно, как он появляется , ну да ладно.

S> Не знаю как в C++ в квадрате но помоему sqr (square of number) есть везде, sqrt (square root) это корень квадратны разница в t на конце

Что такое sqrt я знаю. Я не понимаю как он в формулу попадает.
Re[17]: Создание эффективного контейнера для работы со списк
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 21.06.04 15:32
Оценка:
Здравствуйте, alsemm, Вы писали:




S>> Не знаю как в C++ в квадрате но помоему sqr (square of number) есть везде, sqrt (square root) это корень квадратны разница в t на конце

A>Что такое sqrt я знаю. Я не понимаю как он в формулу попадает.
sqr<> sqrt
sqr(N) = N*N
интеграл от 0 по N n/2 dn = N*N/4;

Во сейчас вспомню интеграл от log(n) по основаню 2. Это затраты на поиск в дереве
дай бог памяти (ой и давнож это было) будет
(N*Log(n) -N)/ Ln(2)
... << RSDN@Home 1.1.0 stable >>
и солнце б утром не вставало, когда бы не было меня
Re[18]: Создание эффективного контейнера для работы со списк
От: alsemm Россия  
Дата: 21.06.04 15:53
Оценка:
Здравствуйте, Serginio1, Вы писали:

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





S>>> Не знаю как в C++ в квадрате но помоему sqr (square of number) есть везде, sqrt (square root) это корень квадратны разница в t на конце

A>>Что такое sqrt я знаю. Я не понимаю как он в формулу попадает.
S> sqr<> sqrt
S> sqr(N) = N*N
????
По вашему sqrt(16) = 256, а мне казалось, что sqrt(16) = 4, вот pow(N, 2) = N*N.
S> интеграл от 0 по N n/2 dn = N*N/4;

S> Во сейчас вспомню интеграл от log(n) по основаню 2. Это затраты на поиск в дереве

S> дай бог памяти (ой и давнож это было) будет
S> (N*Log(n) -N)/ Ln(2)
Re[19]: Создание эффективного контейнера для работы со списк
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 21.06.04 16:01
Оценка:
Здравствуйте, alsemm, Вы писали:


A>????

A>По вашему sqrt(16) = 256, а мне казалось, что sqrt(16) = 4, вот pow(N, 2) = N*N.
S>> интеграл от 0 по N n/2 dn = N*N/4;
Да не SQRT а SQR разница в T
пусть будет pow
... << RSDN@Home 1.1.0 stable >>
и солнце б утром не вставало, когда бы не было меня
Re[20]: Создание эффективного контейнера для работы со списк
От: alsemm Россия  
Дата: 21.06.04 16:06
Оценка:
Здравствуйте, Serginio1, Вы писали:

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



A>>????

A>>По вашему sqrt(16) = 256, а мне казалось, что sqrt(16) = 4, вот pow(N, 2) = N*N.
S>>> интеграл от 0 по N n/2 dn = N*N/4;
S> Да не SQRT а SQR разница в T
S> пусть будет pow
Аааа, Семен Семеныч
Re[5]: От модератора
От: Павел Кузнецов  
Дата: 09.07.04 15:21
Оценка:
Ветка
Автор: ssm
Дата: 18.06.04
с обсуждением "шаблонов" в C# перенесена в форум ".Net".
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re: Создание эффективного контейнера для работы со списком б
От: eugals Россия  
Дата: 05.11.04 08:38
Оценка:
Здравствуйте, Алексей Семенюк, Вы писали:

АС>Статья:


А почему нельзя было воспользоваться спецификой предметной области?
Вроде же в текстовых редакторах существует такая вещь, как "текущая строка", соответственно, кешируя последний запрошенный указатель, а также его индекс, можно было бы получить очень неплохую скорость поиска/редактирования.
Перемещения по тексту тоже обычно происходят последовательно — вверх/вниз на строку/экран. Зная номер текущей строки и имея двусвязный список, вполне реально быстро искать соседние буферы.

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