Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как не надо писать код 
:(
    Опции темы
Earnest
Дата 30.7.2010, 07:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 53
Всего: 183



Внимание! Хвост темы с базаром про ООП\не ООП перенесен в религиозные войны. Ругайтесь там, если охота. А здесь прошу высказываться по теме, если есть что сказать. Все прочее будет удаляться без предупреждения.



--------------------
...
PM   Вверх
Randajad
Дата 18.3.2012, 12:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 295
Регистрация: 15.3.2012

Репутация: 8
Всего: 8



Очень интересное мнение участников про malloc.

Код

#define ARRAY_BUF_SIZE 8


template<typename T>
inline T *nalloc(u32 size, T **p = 0) {
    size *= sizeof(T);

    if(p)
        return *p = (T *)nedalloc::nedrealloc(*p, size);
    return (T *)nedalloc::nedrealloc(0, size);
}

inline void nfree(void *p) {
    nedalloc::nedfree(p);
}

template<typename T>
class array {
public:
    inline array() : len(0), arr(0), real_len(0) {}

    inline ~array() {
        while(len--)
            arr[len].~T();
    }

    inline void resize(u32 nlen) {
        if(len < nlen) {
            if(arr == 0 || real_len < nlen)
                nalloc(real_len = nlen + ARRAY_BUF_SIZE, &arr);

            for(; len != nlen; len++)
                new(arr + len) T;

            return;
        }

        for(; len != nlen; len--)
            arr[len].~T();

        if(len || !arr)
            return;

        nfree(arr);

        arr = 0;
        real_len = 0;
    }

    inline T &operator[](u32 idx) const {
        return arr[idx];
    }

    inline array<T> &operator=(const array<T> &a) {
        resize(a.len, true);

        for(u32 idx = len; idx--; )
            arr[idx] = a.arr[idx];
        return *this;
    }

    template<typename F>
    inline void sort(F f) {
        qsort(arr, len, sizeof(T), f);
    }

    inline void clear() {
        resize(0);
    }

    inline void pop() {
        erase(len - 1);
    }

    inline T *getp() {
        return &get();
    }

    inline T &get() {
        resize(len + 1);
        return arr[len - 1];
    }

    inline T &push(T &t) {
        T &ret = get();
        return ret = t;
    }

    inline T &push(T *t) {
        T &ret = get();
        return ret = *t;
    }

    inline T &push(T t) {
        T &ret = get();
        return ret = t;
    }

    inline void erase(T *t) {
        erase(t - arr);
    }

    inline void erase(T t) {
        for(T *cur = arr, *end = arr + len; cur != end; cur++)
            if(*cur == t) {
                erase(cur);
                return;
            }
    }

    inline void erase(u32 idx) {
        arr[idx].~T();

        if(idx == --len)
            return;
        memmove(arr + idx, arr + idx + 1, (len - idx) * sizeof(T));
    }

    u32 len;
private:
    T *arr;

    u32 real_len;
    inline array<T>(const array<T> &);
};


А что участники думают по поводу этого?
std::vector для классов, которые внутри себя выделяют память не подходит, потому что вектор все время переконструирует и вызывает оператор=(), когда закончилось место в буффере/удаляют элемент из середины массива; это все дико тормозит.

Кстати. Еще в правила: не нужно использовать NULL. Это макрос и он задефайнен где-то там. Лучше 0. Или, с выходом С++0х можно еще nullptr.

Это сообщение отредактировал(а) Randajad - 18.3.2012, 12:33
PM MAIL   Вверх
Фантом
Дата 18.3.2012, 13:36 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Вы это прекратите!
***


Профиль
Группа: Участник Клуба
Сообщений: 1516
Регистрация: 23.3.2008

Репутация: нет
Всего: 49



Цитата(Randajad @  18.3.2012,  13:17 Найти цитируемый пост)

А что участники думают по поводу этого?

Код на C++, в котором в первой же строке константа определяется макросом... что тут еще можно думать?  smile 
PM   Вверх
Randajad
Дата 18.3.2012, 18:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 295
Регистрация: 15.3.2012

Репутация: 8
Всего: 8



И что же вы находите такого плохого в дефайнах препроцессора? smile
PM MAIL   Вверх
bsa
Дата 19.3.2012, 13:18 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



А что тут думать? Вопрос находится в теме "как не надо писать код". Ответ очевиден.  smile 
Самый быстрый доступ к элементам в векторе. Самое быстрое удаление/вставка в середину в списке.
Если тебе не нужен случайный доступ, а достаточно последовательного, то лучше выбрать список.
Если тебе необходим случайный доступ, а размер элементов не больше указателя, то быстрее вектора вряд ли что будет.
Если ты используешь большие массивы больших элементов и случайный доступ необходим, то можно сделать нечто среднее, между списком и вектором. Т.е. в списке у тебя хранятся сами элементы, а в векторе хранятся указатели на них. Таким образом, при добавлении/удалении элементов, вектор будет работать только с простыми указателями (это быстро), а список с элементами. Пример такого контейнера - QList (Qt).
PM   Вверх
Randajad
Дата 25.3.2012, 17:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 295
Регистрация: 15.3.2012

Репутация: 8
Всего: 8



Это все хорошо, но необходим также доступ к элементам в стиле обычного массива. smile
Так что увы, ничего подходящего не нашел, кроме как самописный вариант.
PM MAIL   Вверх
bsa
Дата 26.3.2012, 17:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Цитата(Randajad @  25.3.2012,  18:45 Найти цитируемый пост)
Это все хорошо, но необходим также доступ к элементам в стиле обычного массива.

Цитата
Если ты используешь большие массивы больших элементов и случайный доступ необходим, то можно сделать нечто среднее, между списком и вектором. Т.е. в списке у тебя хранятся сами элементы, а в векторе хранятся указатели на них. Таким образом, при добавлении/удалении элементов, вектор будет работать только с простыми указателями (это быстро), а список с элементами. Пример такого контейнера - QList (Qt). 

PM   Вверх
Randajad
Дата 27.3.2012, 08:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 295
Регистрация: 15.3.2012

Репутация: 8
Всего: 8



Я имел ввиду чтобы:
array<int> arr;
Было равно int arr[];
И все элементы стояли друг за другом в одном куске памяти. smile
PM MAIL   Вверх
baldina
Дата 27.3.2012, 10:26 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 32
Всего: 101



Цитата(Randajad @  18.3.2012,  12:17 Найти цитируемый пост)
 вектор все время переконструирует и вызывает оператор=()

если у объекта тривиальный конструктор/деструктор накладных немного. если нетривиальный, объект (или объекты с ним связанные) может быть обескуражен неожиданной сменой адреса. так что именно vector подходит "для классов, которые внутри себя выделяют память".
память кстати по-разному выделять можно. скажем, копирование при записи. так что это скорее проблема класса-содержимого, а не контейнера.
желание иметь элементы в памяти "одним куском", причем именно элементы, а не указатели законно, но не понятно. приведите пример, когда это действительно необходимо. мне в голову приходит только работа с низкоуровневыми библиотеками, но они в основном работают с элементарными типами данных, для которых перемещение в vector реализовано как раз через memmove. кстати. никто не мешает вам сделать свою специализацию класса vector.

PM MAIL   Вверх
Randajad
Дата 14.4.2012, 17:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 295
Регистрация: 15.3.2012

Репутация: 8
Всего: 8



Объекты внутри себя не хранят ссылок друг на друга, в этом вся фишка.
Выделение через new памяти для каждого объекта не хорошая идея потому, что размер объекта маленький, а их число порядка десятков тысяч. Таким образом из-за выравнивания и данных менеджера памяти получится слишком большое количество памяти "впустую".
PM MAIL   Вверх
baldina
Дата 14.4.2012, 21:44 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 32
Всего: 101



Цитата

Тони Хоар впервые произнёс, а Дональд Кнут впоследствии часто повторял известное высказывание: «Преждевременная оптимизация — это корень всех бед»

PM MAIL   Вверх
heavix
Дата 15.5.2012, 11:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 60
Регистрация: 10.8.2007

Репутация: нет
Всего: нет



Цитата

     11. Функции принимающие 10 (да-да, 10) параметров.


10?)) Это еще ничего))) Вот сейчас у меня проект, в котором есть функция принимающая 43 параметра, причем одного типа mxArray... Корень всех бед проекта...
И самое паршивое что я сделать ничего не могу, т.к эта функция дергается из длл-ки написанной в матлабе( А математику делаю не я... Вот и наступает вынос мозга когда человек делающий мат часть начинает требовать передачи параметров номер 3,9,12 как uint8, 14,16 как стринг... но все нуно конвертить в mxArray ))   
PM MAIL   Вверх
ТарасАтавин
Дата 29.8.2013, 18:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 370
Регистрация: 26.8.2013

Репутация: нет
Всего: нет



Цитата(chipset @  18.3.2006,  07:09 Найти цитируемый пост)
11. Функции принимающие 10 (да-да, 10) параметров.
А почему так мало? Уж если автор идиот, то должна быть пара тысяч.

Добавлено @ 18:51
Цитата(Ignat @  18.3.2006,  12:38 Найти цитируемый пост)
Ну это я сильно поскромничал, 1000 строк - это только та часть, с которой я работаю, даже, наверное 1500-2000 будет точнее,
Тысяч 30 - это то, что читается в оперативу и анализируется на диване. А жалкие две и хорошим то стилем стоит брать чужие в единственном случае - если писаны наставником/преподавателем/автором книги, которую можно рекомендовать на роль учебника. И только за образец. Потому что их быстрее переписать, не заглядывая, чем пристроить. Этот объём - не тот случай, когда оправдано разделение труда в команде.

Добавлено @ 18:59
Цитата(UnrealMan @  30.3.2006,  14:26 Найти цитируемый пост)
А чем собс-но плох malloc? В случае, когда используются нетривиальные объекты (с конструктором, деструктором), и требуется перевыделение памяти с сохранением данных (realloc), использование new и delete – явно не самое удачное решение. 
Как раз единственно допустимое. Маллок/реаалок - это для скаляров. 


Это сообщение отредактировал(а) ТарасАтавин - 29.8.2013, 19:09


--------------------
Не так всё плохо, как оно есть на самом деле.
PM MAIL   Вверх
ТарасАтавин
Дата 29.8.2013, 19:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 370
Регистрация: 26.8.2013

Репутация: нет
Всего: нет



Самое веселое - это писать вообще без отсупов, а на плюсах так ещё и всё в одну строку.

Добавлено через 1 минуту и 11 секунд
Вот ещё пособие, как делать не надо: 
Код
int factorial(int x)
{
 return factorial(x-1)*x;
}


Добавлено через 4 минуты и 1 секунду
И поминавшийся здесь явный вызов конструктора. Конструктор и деструктор придуманы именно для того, чтоб вызываться автоматически, чтоб уж точно не забыть из вызвать и, наоборот, не забыть, что уже вызвал.


--------------------
Не так всё плохо, как оно есть на самом деле.
PM MAIL   Вверх
ТарасАтавин
Дата 30.8.2013, 04:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 370
Регистрация: 26.8.2013

Репутация: нет
Всего: нет



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


--------------------
Не так всё плохо, как оно есть на самом деле.
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1025 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.