Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Расположение подряд экземпляров класса (С++)

31K
27 ноября 2008 года
dreamer.mas
69 / / 15.11.2008
Есть некоторый класс (например, MyClass). Есть указатель на доступную область памяти размером N*sizeof(MyClass). Возможно ли расположить в этой области памяти N экземпляров класса, если у класса конструктор имеет аргументы? Задача состоит в том, чтобы последовательно работать с экземплярами класса с как можно меньшим количеством вычислений: когда переменная MyClass * p указывает на начало области - работать с первым экземпляром, при увеличении p на sizeof(MyClass) - со вторым экземпляром и т.д.
31K
28 ноября 2008 года
dreamer.mas
69 / / 15.11.2008
Прошу прощения, ответ нашел сам.
355
28 ноября 2008 года
<SCORP>
786 / / 21.10.2006
ну память под массивы объектов так и выделяется
а какое решение Вы нашли? поделитесь с общественностью :)
31K
28 ноября 2008 года
dreamer.mas
69 / / 15.11.2008
Всё оказалось весьма просто:

 
Код:
#include <new>

...

T * p;
new (p) T();


p - это как раз та самая ссылка. Только перед этим нужно установить p на свободный участок памяти.
288
28 ноября 2008 года
nikitozz
1.2K / / 09.03.2007
Цитата: dreamer.mas
Есть некоторый класс (например, MyClass). Есть указатель на доступную область памяти размером N*sizeof(MyClass). Возможно ли расположить в этой области памяти N экземпляров класса, если у класса конструктор имеет аргументы? Задача состоит в том, чтобы последовательно работать с экземплярами класса с как можно меньшим количеством вычислений: когда переменная MyClass * p указывает на начало области - работать с первым экземпляром, при увеличении p на sizeof(MyClass) - со вторым экземпляром и т.д.



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

31K
28 ноября 2008 года
dreamer.mas
69 / / 15.11.2008
Ситуация усложняется тем, что количество экземпляров класса может варьироваться в достаточно больших пределах (плюс/минус несколько сотен или тысяч), а память лишней не бывает. Так что варианты вроде T t[100] не подойдут.
355
28 ноября 2008 года
&lt;SCORP&gt;
786 / / 21.10.2006
эм... ну тогда вы легко можете наткнуться на ситуацию, что при попытке размещения следующего объекта у вас не будет досточного объёма памяти в вашей непрерывной области. хотя вообще оперативной памяти достаточное количество будет
31K
28 ноября 2008 года
dreamer.mas
69 / / 15.11.2008
Выделяется ровно столько памяти, сколько объектов должно быть там. Еще в первом после я написал:
Цитата:
Есть указатель на доступную область памяти размером N*sizeof(MyClass). Возможно ли расположить в этой области памяти N экземпляров класса...

355
29 ноября 2008 года
&lt;SCORP&gt;
786 / / 21.10.2006
тогда вполне можено сделать T *aLotOfTs = new T[n], разве нет?
31K
29 ноября 2008 года
dreamer.mas
69 / / 15.11.2008
А на этот счет я тоже писал:
Цитата:
если у класса конструктор имеет аргументы

3
29 ноября 2008 года
Green
4.8K / / 20.01.2000
А почему бы не использовать стандартный контейнер?
31K
29 ноября 2008 года
dreamer.mas
69 / / 15.11.2008
Какой именно? Если Вы имеете в виду всякие CList и прочие, то, во-первых, я уже указывал, что важна скорость работы, а эти контейнеры хз как организованы. Ну и, во-вторых, важна переносимость приложения между осями (с Windows на Linux/Unix).
3
29 ноября 2008 года
Green
4.8K / / 20.01.2000
Цитата: dreamer.mas
Какой именно?


Стандартные контейнеры - это vector, list и т.д.

Цитата: dreamer.mas

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


Ну так разберись, как "организованы", а не изобретай велосипед.

Цитата: dreamer.mas

Ну и, во-вторых, важна переносимость приложения между осями (с Windows на Linux/Unix).


На то они и СТАНДАРТНЫЕ контейнеры.

31K
29 ноября 2008 года
dreamer.mas
69 / / 15.11.2008
Цитата: Green
Ну так разберись, как "организованы", а не изобретай велосипед.

А с чего, собственно, наезд? Вам не нравится найденный мною способ? Причем реализация его работает отлично.

3
29 ноября 2008 года
Green
4.8K / / 20.01.2000
Цитата: dreamer.mas
А с чего, собственно, наезд? Вам не нравится найденный мною способ? Причем реализация его работает отлично.


Это не наезд, а совет.
А "найденный" способ является обычной практикой, только вот сам по себе он не имеет особого смысла, а конструирование на его базе контейнера является созданием (ущербного) велосипеда.

31K
29 ноября 2008 года
dreamer.mas
69 / / 15.11.2008
Специально для вашей персоны:
Код:
#include <iostream>
#include <list>
#include <malloc.h>
#include <new>
#include <time.h>

using namespace std;

class MyClass
{
private:
    double _a;
    double _b;
    double _c;

public:
    MyClass(double a, double b, double c)
    {
        _a = a;
        _b = b;
        _c = c;
    }

    void Get(double * a, double * b, double * c)
    {
        (*a) = _a;
        (*b) = _b;
        (*c) = _c;
    }
};

int main()
{
    list<MyClass> doubleList;
    list<MyClass>::iterator iter;
    MyClass * d = (MyClass *)malloc(sizeof(MyClass) * 50000);

    int i;
    for (i=0; i<50000; i++)
    {
        doubleList.push_back(MyClass(i,i+1,i+2));
        new (d + i) MyClass(i,i+1, i+2);
    }

    clock_t begin, end;
    double a,b,c;

    begin = clock();

    for (iter = doubleList.begin(); iter != doubleList.end(); iter++)
    {
        iter->Get(&a, &b, &c);
    }

    end = clock();
    cout << end - begin << endl;

    begin = clock();

    for (i=0; i<50000; i++)
    {
        (d+i)->Get(&a, &b, &c);

    }
    end = clock();
    cout << end - begin << endl;

}
Может Вы окажите честь скромному плебею убедиться, что при очень больших количествах экземпляров Ваш list выглядит весьма плачевно, уступая в производительности в 15-200 раз (в зависимости от теста)?
3
29 ноября 2008 года
Green
4.8K / / 20.01.2000
Цитата: dreamer.mas

Может Вы окажите честь скромному плебею убедиться, что при очень больших количествах экземпляров Ваш list выглядит весьма плачевно, уступая в производительности в 15-200 раз (в зависимости от теста)?


Советую разобраться, что есть list (не мой, а языка C++), что есть vector. В чем различия между ними и их назначения.
После изучения тобой этого материала есть смысл продолжать спор.

31K
29 ноября 2008 года
dreamer.mas
69 / / 15.11.2008
Что Вам не нравится? Хорошо, заменил list на vector (о чудо, в MSDN про вектор пишут "fast random access to any element", наверно это то, что нам нужно?). Заменил второй for на счетчик по i и вызов doubleList.Get(&a, &b, &c) - результат лучше, но в большинстве тестов, тогда как мой метод проходит за 0 миллисекунд, vector требует не меньше 16-ти. Во всех тестах vector показал себя хуже (максимальное время выполнения моего метода - 15 мс).
3
29 ноября 2008 года
Green
4.8K / / 20.01.2000
Цитата: dreamer.mas
Что Вам не нравится? Хорошо, заменил list на vector (о чудо, в MSDN про вектор пишут "fast random access to any element", наверно это то, что нам нужно?). Заменил второй for на счетчик по i и вызов doubleList.Get(&a, &b, &c) - результат лучше, но в большинстве тестов, тогда как мой метод проходит за 0 миллисекунд, vector требует не меньше 16-ти. Во всех тестах vector показал себя хуже (максимальное время выполнения моего метода - 15 мс).


Что мне не нравится?
В общем случае то, что люди, не зная и не умея пользоваться инструментом, начинают изобретать велосипеды и находят любые оправдания своего нежелания учиться.

Какие-то подвижки уже есть, это хорошо.
Изучай далее. Есть для вектора спец. макрос компиляции для увеличения производительности.
Ну на счет того, что строить надо не в режиме отладки и с соотв. параметрами оптимизации, наверное, напоминать не надо? :)

P.S. А почему ты так напираешь на производительность? Это по-твоему единственный критерий предпочтения? :)

P.P.S. Кстати, ты поспешил назвать "метод" своим именем. Будешь удивлен, но тот же вектор оперирует таким же способом. Так что сравниваешь ты не "способы", а свой контейнер со стандартным.

31K
29 ноября 2008 года
dreamer.mas
69 / / 15.11.2008
Цитата: Green
В общем случае то, что люди, не зная и не умея пользоваться инструментом, начинают изобретать велосипеды и находят любые оправдания своего нежелания учиться.

Да-да-да. Просто мне как-то на секунду показалось, что меня GCC при попытке скомпилить такой код со всеми макросами и прочим пошлет куда подальше. Но это ладно.

Цитата:
Изучай далее. Есть для вектора спец. макрос компиляции для увеличения производительности.

Единственное, что нашел - это _SECURE_SCL, который никакого эффекта не дал.

Цитата:
Ну на счет того, что строить надо не в режиме отладки и с соотв. параметрами оптимизации, наверное, напоминать не надо? :)

Да вроде не вчера компьютером пользоваться научился.

Цитата:
P.S. А почему ты так напираешь на производительность? Это по-твоему единственный критерий предпочтения? :)

Вы предлагаете пожертвовать приложением (в котором, кстати, производительность - один из самых главных критериев) в ущерб сомнительной "красивости" кода?

3
29 ноября 2008 года
Green
4.8K / / 20.01.2000
Цитата: dreamer.mas
Да-да-да. Просто мне как-то на секунду показалось, что меня GCC при попытке скомпилить такой код со всеми макросами и прочим пошлет куда подальше.


Что делать, когда кажется, знаешь?

Цитата: dreamer.mas

Но это ладно.Единственное, что нашел - это _SECURE_SCL, который никакого эффекта не дал.


Просто, ты не умеешь им пользоваться. Ищи по форуму.

Цитата: dreamer.mas

Вы предлагаете пожертвовать приложением (в котором, кстати, производительность - один из самых главных критериев) в ущерб сомнительной "красивости" кода?


Я предлагаю не изобретать велосипеды.
И красивость кода тут не последнее, но и не на первом месте.
Еще предлагаю научиться пользоваться С++ и научиться правильно оптимизировать программы.

31K
29 ноября 2008 года
dreamer.mas
69 / / 15.11.2008
Цитата: Green
Просто, ты не умеешь им пользоваться. Ищи по форуму.

Ну я как бы и про директиву #define не вчера узнал... При ее использовании время проведения операции с list снижается до 0 мс примерно в таком проценте тестов, в каком время использование второго метода доходит до 15 мс. В основном всё те же 16 мс. Не знаю, может это уже какие-то нюансы clock... При увеличении количества объектов до 500000 обнаруживается выгода по времени как минимум в три раза.

3
29 ноября 2008 года
Green
4.8K / / 20.01.2000
Цитата: dreamer.mas
Ну я как бы и про директиву #define не вчера узнал...


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

Цитата: dreamer.mas

При ее использовании время проведения операции с list снижается до 0 мс примерно в таком проценте тестов, в каком время использование второго метода доходит до 15 мс. В основном всё те же 16 мс. Не знаю, может это уже какие-то нюансы clock... При увеличении количества объектов до 500000 обнаруживается выгода по времени как минимум в три раза.


При чем тут list?

И еще раз: при чем тут вообще "скорость" на таких примитивных примерах?
А что на счет скорости разработки? Что на счет преждевременной оптимизации?

Подведу итог.
Мой совет: изучай инструмент, которым пользуешься. Не изобретай велосипед без крайней необходимости (твоя необходимость была вызвана незнанием С++, а не погоней за производительностью, которую ты сейчас пытаешься изобразить).

Тебе был предложено подходящее решение твоей проблемы. Решение, которое работает в миллионах программ, уверен, что не менее требовательных по производительности.
Можешь воспользоваться им или нет. Дело твое.

Тема закрыта.

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог