Re[49]: Об эффективности программ
От: IT Россия linq2db.com
Дата: 05.11.05 03:30
Оценка: :))
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Все, извини, но это письмо будет точно последним. Времени больше на эти дискуссии нет — увы, заказчик прислал наконец спецификации проекта, и он именно на С# .

Заказчик всегда прав!
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[12]: Параллельные билды для C++
От: VladD2 Российская Империя www.nemerle.org
Дата: 05.11.05 13:39
Оценка:
Здравствуйте, IT, Вы писали:

IT>А что они такое пишут?




IT>Индусы что-ли?


У тебя уже на них фобия.

Нет конечно. Но не нужно быть индусом чтобы на плюсах создать проект который будет компилироваться пол часа на одной машине.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[13]: Параллельные билды для C++
От: IT Россия linq2db.com
Дата: 05.11.05 14:20
Оценка:
Здравствуйте, VladD2, Вы писали:

IT>>Индусы что-ли?


VD>У тебя уже на них фобия.


У меня на них миллиард фобий. Или сколько их там.

VD>Нет конечно. Но не нужно быть индусом чтобы на плюсах создать проект который будет компилироваться пол часа на одной машине.


Они не на Watcom случайно проект делают, который состоит из одних шаблонов? Тогда в лёгкую. А так надо очень постараться.
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[6]: Об эффективности программ
От: Alexey Axyonov Украина  
Дата: 07.11.05 11:21
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Это старый АПИ. Оно не будет работать на машинах с новым вордом. По крайней мере на моей машине где стоит Word 2003 оно не работает.


Влад может на счет АПИ ты и прав, но у меня Word 2003 SP2 и оно работает.
... << RSDN@Home 1.2.0 alpha rev. 619>>
Re[7]: Об эффективности программ
От: VladD2 Российская Империя www.nemerle.org
Дата: 07.11.05 13:49
Оценка: :)
Здравствуйте, Alexey Axyonov, Вы писали:

VD>>Это старый АПИ. Оно не будет работать на машинах с новым вордом. По крайней мере на моей машине где стоит Word 2003 оно не работает.


AA>Влад может на счет АПИ ты и прав, но у меня Word 2003 SP2 и оно работает.


В SP2 похоже многие глюки пофиксили. Может услышали как я разоряюсь?
Но SP2 появился только сейчас. А Ворду уже много лет и как минимум 10 из них он содержал в себе один и те же глюки.

Кстати, точно сказать, что глюки пофиксили пока не могу, так как времени прошло немного с выхода SP2. Но через месяцок другой скажу.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[7]: Закон Мура умер
От: DJ KARIES Россия  
Дата: 13.11.05 17:15
Оценка:
Здравствуйте, FR, Вы писали:

GN>>Думаю для определённых (узких) классов задач решения будут постепенно возникать. Я бы и сам с радостью купил писюк, который весь (кроме монитора) находится в клавиатуре .


FR>Давно забытое старое? (синклер, микроша, вектор, поиск)

FR>Да и сейчас есть тот же mac-mini

Мне вот нравятся маленькие такие ноуты, с книжку размером, с dvd-rw приводом, экранчиком 10".
Однако стоят такие хреновинки 50-60т.р. ($1600-2000).
Вот за 300 баксов бы я такой себе хоть щщас взял

Что интересно, стандартные большие ноуты стоят в 2-3 раза дешевле маленьких.

Когда цены на миниатюрные решения станут адекватными для простых граждан?
http://dkdens.narod.ru http://giref.forthworks.com
Re: Об эффективности программ
От: Андрей Ушаков Финляндия  
Дата: 14.11.05 12:44
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Компилятор с Фортрана на 96 КБайтах работал, c PL/1 — даже на 64 Кбайтах (до сих

PD>пор не знаю, почему — PL/1 сложнее Фортрана), линкеру тоже 96 Кбайт хватало,

Они были жутко оверлейные... Чем им было доступно больше памяти, тем они быстрее работали. Оптимизирующему компилялятору PL/1 памяти было нужно заметно больше, чем стандартному.

-andy-
Re[23]: Об эффективности программ
От: vdimas Россия  
Дата: 28.02.06 23:01
Оценка:
Здравствуйте, WolfHound, Вы писали:

Невероятно Это все действительно Wolfhound написал, или нас разыграли?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[23]: Об эффективности программ
От: vdimas Россия  
Дата: 28.02.06 23:01
Оценка:
Здравствуйте, Sinclair, Вы писали:


S>Совершенно верно! Но, к сожалению, это была бы совсем другая программа.

S>И Павел не будет ее писать. Потому, что strlen — это медленная операция, а он-то как раз хотел сэкономить лишний проход по данным.

а кто мешает юзать snprintf()? Как раз для таких случаев предназначена, свои проверки можно не делать.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[8]: Об эффективности программ (уровень языка)
От: vdimas Россия  
Дата: 07.03.06 18:20
Оценка:
Здравствуйте, GlebZ, Вы писали:

>>> А string вообще кошмар, но зато жутко удобный.

ПК>>Это к уровню языка отношения не имеет.
GZ>В честь чего. В С++ два основных типа строк.(пишу именно основных, чтоб не наезжали) Строка и нестрока, то есть string и char[]. string объект ООП — char[] наследие С. Кто из них высокоуровневая конструкция, а кто тормозная?

быстродействие выделения/удаления std::string напрямую зависит от алокатора. Все остальные операции сравнимы по эффективности... Некоторые алгоритмы могут работать гораздо быстрее за счет агрессивного инлайнинга.

Напиши аллокатор статического типа (или попроси меня прислать исходник), и ты получишь ООП-строку, не уступающую char[].
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[9]: Об эффективности программ
От: vdimas Россия  
Дата: 07.03.06 18:20
Оценка:
Здравствуйте, mrozov, Вы писали:

M>Не думаю, что стоит вот так категорично говорить о том, что вам должны инструментальные средства.


У-у-у, еще как должны, если хотят называться инструментальными, а не геммороидальными, например.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[9]: Об эффективности программ (уровень языка)
От: GlebZ Россия  
Дата: 08.03.06 16:40
Оценка:
Здравствуйте, vdimas, Вы писали:

V>быстродействие выделения/удаления std::string напрямую зависит от алокатора. Все остальные операции сравнимы по эффективности... Некоторые алгоритмы могут работать гораздо быстрее за счет агрессивного инлайнинга.


V>Напиши аллокатор статического типа (или попроси меня прислать исходник), и ты получишь ООП-строку, не уступающую char[].

Ну уступающего char[] в стеке?
... << RSDN@Home 1.2.0 alpha rev. 0>>
Re[10]: Об эффективности программ (уровень языка)
От: vdimas Россия  
Дата: 08.03.06 16:50
Оценка:
Здравствуйте, GlebZ, Вы писали:

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


V>>быстродействие выделения/удаления std::string напрямую зависит от алокатора. Все остальные операции сравнимы по эффективности... Некоторые алгоритмы могут работать гораздо быстрее за счет агрессивного инлайнинга.


V>>Напиши аллокатор статического типа (или попроси меня прислать исходник), и ты получишь ООП-строку, не уступающую char[].

GZ>Ну уступающего char[] в стеке?

именно
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[11]: Об эффективности программ (уровень языка)
От: GlebZ Россия  
Дата: 08.03.06 17:14
Оценка:
Здравствуйте, vdimas, Вы писали:

V>>>Напиши аллокатор статического типа (или попроси меня прислать исходник), и ты получишь ООП-строку, не уступающую char[].

GZ>>Ну уступающего char[] в стеке?

V>именно

Гонишь. Давай поясню что такое char[]. В отличие от string — это не массив, а всего лишь набор объектов. И даже копирование строк можно делать несколькими способами — перекопируя память через memmove, strcpy, или вручную построенным циклом. То есть способов не нарушающих инкапсуляцию char[] до фигищи. И кое какие из них — менее эффективны а какие-то более эффективны. К тому же strcpy можно легко проинлайнить, и я сомневаюсь что кто-то его обгонит, даже теоретически.
... << RSDN@Home 1.2.0 alpha rev. 0>>
Re[12]: Об эффективности программ (уровень языка)
От: vdimas Россия  
Дата: 08.03.06 17:18
Оценка:
Здравствуйте, GlebZ, Вы писали:

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


V>>>>Напиши аллокатор статического типа (или попроси меня прислать исходник), и ты получишь ООП-строку, не уступающую char[].

GZ>>>Ну уступающего char[] в стеке?

V>>именно

GZ>Гонишь. Давай поясню что такое char[]. В отличие от string — это не массив, а всего лишь набор объектов. И даже копирование строк можно делать несколькими способами — перекопируя память через memmove, strcpy, или вручную построенным циклом. То есть способов не нарушающих инкапсуляцию char[] до фигищи. И кое какие из них — менее эффективны а какие-то более эффективны. К тому же strcpy можно легко проинлайнить, и я сомневаюсь что кто-то его обгонит, даже теоретически.

а разве ты только копируешь строки??? мне казалось, что ты их еще сравниваешь и в коллекции ложишь и т.д.

В общем, могу дать стековый аллокатор и не смущай народ
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[12]: Об эффективности программ (уровень языка)
От: Cyberax Марс  
Дата: 08.03.06 19:02
Оценка:
GlebZ wrote:
> V>именно
> Гонишь.
Пример из моей BTL (Bicycle Template Library ) — политика хранения,
использующая небольшой стековый буфер для оптимизации:
///////////////////////////////////////////////////////////////////////////////////////
////// Small-Storage-Optimization
///////////////////////////////////////////////////////////////////////////////////////
namespace aux
{
    //This union is used to ensure that SSO storage elements will be 
properly aligned.
    template<size_t small_storage_size, class StorageT> union sso_storage_data
    {
        typedef typename StorageT::value_type value_type;

        typename boost::type_with_alignment<
            (boost::alignment_of<StorageT>::value > 
boost::alignment_of<value_type>::value)
            ? boost::alignment_of<StorageT>::value
            : boost::alignment_of<value_type>::value
            >::type a;
        char storage_[sizeof(StorageT)];
        char data_[small_storage_size*sizeof(value_type)];
    };

    struct dummy_type { int dummy_; };
};

template<size_t small_storage_size,class StorageT> class sso_storage :
    private boost::noncopyable,
    //Use EBO for allocator. Note: workaround for VC bug!
    private StorageT::allocator_type::template rebind<aux::dummy_type>::other
{
    //There is no sense in zero-sized sso!
    BOOST_STATIC_ASSERT(small_storage_size!=0);
    typedef typename StorageT::allocator_type::template rebind<
        aux::dummy_type>::other rebound_alloc;

    //Type of this class, useful for generic code
    typedef sso_storage<small_storage_size,StorageT> this_class;
    //Type of the small storage
    typedef aux::sso_storage_data<small_storage_size,StorageT> data_type;

    //Magic size indicates we've reverted to the main storage.
    static const size_t magic_size=small_storage_size+1;

    //small_storage_size is insanely large - magic_size overflows!
    BOOST_STATIC_ASSERT((magic_size>small_storage_size));
    //SSO might be used only for POD-like types due to exception-safety 
issues. TODO: add support for nothrowing copyctors.
    BOOST_MPL_ASSERT((bitwise_moveable<typename StorageT::value_type>));
public://protected:
    typedef StorageT delegate_storage;

    typedef typename StorageT::move_traits move_traits;
    typedef typename StorageT::value_type value_type;
    typedef typename StorageT::size_type size_type;
    typedef typename StorageT::allocator_type allocator_type;
    typedef sso_const_iterator<this_class> const_iterator;
    typedef sso_iterator<this_class> iterator;

    //Storage construction
    explicit sso_storage(const allocator_type &_alloc=allocator_type()) : 
rebound_alloc(_alloc), size_()
    {
    }

    //Destructor:
    ~sso_storage()
    {
        reset();
    }

    //Data accessor methods:
    value_type* begin_ptr()
    {
        if (size_==magic_size)
            return get_storage().begin_ptr();
        return reinterpret_cast<value_type*>(buffer_.data_);
    }
    const value_type* begin_ptr() const
    {
        return const_cast<this_class*>(this)->begin_ptr();
    }
    iterator begin()
    {
        if (size_==magic_size)
            return iterator(get_storage().begin());
        else
            return iterator(begin_ptr(),true);
    }
    const_iterator begin() const
    {
        //Note we have to remove constantness from the delegate iterator.
        if (size_==magic_size)
            return const_iterator((const_cast<StorageT&>(get_storage())).begin());
        else
            return const_iterator(begin_ptr(),true);
    }

    value_type* end_ptr()
    {
        if (size_==magic_size)
            return get_storage().end_ptr();
        return reinterpret_cast<value_type*>(buffer_.data_)+size_;
    }
    const value_type* end_ptr() const
    {
        return const_cast<this_class*>(this)->end_ptr();
    }
    iterator end()
    {
        if (size_==magic_size)
            return iterator(get_storage().end());
        else
            return iterator(end_ptr(),true);
    }
    const_iterator end() const
    {
        //Note we have to remove constantness from the delegate iterator.
        if (size_==magic_size)
            return const_iterator((const_cast<StorageT&>(get_storage())).end());
        else
            return const_iterator(end_ptr(),true);
    }

    //Size/capacity:
    size_type size() const
    {
        if (size_==magic_size)
            return get_storage().size();
        return size_;
    }

    size_type max_size() const
    {
        size_type sz;
        if (size_==magic_size)
            sz=get_storage().max_size();
        else
            sz=StorageT(*this).max_size();
        assert(sz>small_storage_size); //Sanity check
        return sz;
    }

    size_type capacity() const
    {
        if (size_==magic_size)
            return get_storage().capacity();
        return small_storage_size;
    }

    bool empty() const
    {
        return size()==0;
    }

    void set_size(size_type _new_size)
    {
        assert(_new_size<=capacity());
        if (size_==magic_size)
            get_storage().set_size(_new_size);
        else
            size_=_new_size;
    }

    allocator_type get_allocator_inst() const
    {
        return allocator_type(*this); 
//const_cast<allocator_type&>(allocator_type(*this));
    }

    void reserve(size_type _new_size)
    {
        if (_new_size<=capacity())
            return;
        if (_new_size>max_size())
            throw ::std::length_error("This storage can't handle such allocations");

        if (size_==magic_size) //SSO is inactive
            get_storage().reserve(_new_size);
        else
        {
            //SSO is active, need to disable it.
            allocator_type alloc(get_allocator_inst());
            StorageT tmp(alloc);
            tmp.reserve(_new_size);
            move_traits::move(begin_ptr(),end_ptr(),tmp.begin_ptr(),alloc);
            tmp.set_size(size());
            reset();            

            create_storage();
            get_storage().move_from(tmp);
        }
    }

    void copy_from(const this_class &_other)
    {
        reset();
        if (_other.size_==magic_size) //Check if SSO is inactive.
        {
            create_storage();
            get_storage().copy_from(_other.get_storage());
        }
        else
        {
            assert(_other.size()<=small_storage_size); //Data should fit into 
small buffer.
            allocator_type alloc(get_allocator_inst());
            //No need to call reserve, because we can't hit reallocation.
            move_traits::copy(_other.begin_ptr(),_other.end_ptr(),begin_ptr(),alloc);
            set_size(_other.size());
        }
    }

    void move_from(this_class &_other)
    {
        reset();
        if (_other.size_==magic_size) //Check if SSO is inactive.
        {
            create_storage();
            get_storage().move_from(_other.get_storage());
            _other.reset();
        }
        else
        {
            assert(_other.size()<=small_storage_size); //Data should fit into 
small buffer.
            allocator_type alloc(get_allocator_inst());
            //No need to call reserve, because we can't hit reallocation.
            move_traits::move(_other.begin_ptr(),_other.end_ptr(),
                begin_ptr(),alloc); //May NOT throw.
            set_size(_other.size());
            _other.reset();
        }
    }

    bool vacuum()
    {
        if (size_==magic_size)
            return get_storage().vacuum();
        return false; //We can't vacuum static storage.
    }

    void mutating()
    {
        if (size_==magic_size)
            get_storage().mutating();
    }

    void swap(this_class & _other)
    {
        //Check if SSO is inactive - in this case just delegate swap to the 
underlaying storages.
        if (size_==magic_size && _other.size_==magic_size)
            get_storage().swap(_other.get_storage());
        else
        {
            //SSO is active at least on one storage, have to use slower swap.
            if (size_==magic_size || empty()) //SSO is active on the other storage.
            {
                //Move our data to the temporary storage (if it's present).
                StorageT tmp(get_allocator_inst());
                if (!empty())
                    tmp.move_from(get_storage());
                reset();

                //Move data from _other to our small buffer
                move_from(_other);

                _other.create_storage();
                _other.get_storage().move_from(tmp);
            } else
                _other.swap(*this); //This will hit previous branch on recursion.
        }
    }

    void reset()
    {
        if (size_==magic_size)
            destroy_storage();
        else
        {
            for(value_type* f=begin_ptr();f!=end_ptr();f++)
                f->~value_type();
            size_=0;
        }
    }

public: //Make custom methods accessible to client.
    bool sso_active() const
    {
        return size_!=magic_size;
    }
    StorageT& get_underlying_storage()
    {
        assert(!sso_active());
        return get_storage();
    }

private:

    void create_storage()
    {
        assert(size_==0); //Storage must be clean
        allocator_type alloc(get_allocator_inst());
        new(buffer_.storage_) StorageT(alloc);
        size_=magic_size;
    }

    void destroy_storage()
    {
        get_storage().~StorageT();
        size_=0;
    }

    StorageT& get_storage()
    {
        assert(size_==magic_size);
        return reinterpret_cast<StorageT&>(buffer_.storage_);
    }

    const StorageT& get_storage() const
    {
        assert(size_==magic_size);
        return reinterpret_cast<const StorageT&>(buffer_.storage_);
    }

    data_type buffer_;
    size_type size_;
};

Поддерживается автоматическое переключение на другую политику хранения,
если размер буффера оказывается недостаточным. В следующей версии еще
добавится более эффективная поддержка для контейнеров, где не нужен
непрерывный блок памяти.

Размер статического хранилища задается параметром темплейта. При желании
можно использовать alloca и задавать размер динамически.
Posted via RSDN NNTP Server 2.0
Sapienti sat!
Re[13]: Об эффективности программ (уровень языка)
От: GlebZ Россия  
Дата: 08.03.06 21:21
Оценка:
Здравствуйте, vdimas, Вы писали:

V>В общем, могу дать стековый аллокатор и не смущай народ

А он нужен?
... << RSDN@Home 1.2.0 alpha rev. 0>>
Re[14]: Об эффективности программ (уровень языка)
От: vdimas Россия  
Дата: 08.03.06 23:15
Оценка:
Здравствуйте, GlebZ, Вы писали:

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


V>>В общем, могу дать стековый аллокатор и не смущай народ

GZ>А он нужен?

угу, тем кому позарез надо char[] в стеке.
Нет ничего проще:

аллокатор, разумеется, подойдет не только для строк, ключевые моменты выделил жирным:

   template<class _Ty, size_t N>
    class FixedBuffAllocator
        : public std::_Allocator_base<_Ty> 
    {    
            _Ty buffer[N];

    public:
        typedef std::_Allocator_base<_Ty> _Mybase;
        typedef typename _Mybase::value_type value_type;

        typedef value_type *pointer;
        typedef value_type &reference;
        typedef const value_type *const_pointer;
        typedef const value_type &const_reference;

        typedef _SIZT size_type;
        typedef _PDFT difference_type;

        template<class _Other>
        struct rebind {    
            typedef FixedBuffAllocator<_Other, N> other;
        };

        pointer address(reference _Val) const
        { return (&_Val); }

        const_pointer address(const_reference _Val) const
        { return (&_Val); }

        FixedBuffAllocator() { }

        FixedBuffAllocator(const FixedBuffAllocator<_Ty, N>&) {
            // do nothing because containers do copying
        }

        template<class _Other, size_t N2>
        FixedBuffAllocator(const FixedBuffAllocator<_Other, N2>&) {    
            // do nothing because containers do copying
        }

        template<class _Other, size_t N2>
            FixedBuffAllocator<_Ty, N>& operator=(const FixedBuffAllocator<_Other, N2>&)
        {    
            // do nothing because containers do copying
            return (*this);
        }

        void deallocate(pointer _Ptr, size_type)
        { /* do nothing */ }

        pointer allocate(size_type _Count)
        {
            if(_Count>N)
                throw std::out_of_range("FixedBuffAllocator<>::allocate()");
            return buffer; 
        }

        pointer allocate(size_type _Count, const void *)
        { return allocate(_Count); }

        void construct(pointer _Ptr, const _Ty& _Val) {    _Construct(_Ptr, _Val);}
        void destroy(pointer _Ptr) { _Destroy(_Ptr); }
        size_t max_size() const { return N; }
    };

    // allocator TEMPLATE OPERATORS
    template<class _Ty, size_t N1,
    class _Other, size_t N2> inline
        bool operator==(const FixedBuffAllocator<_Ty, N1>&, const FixedBuffAllocator<_Other, N2>&)
    { return N1==N2; }

    template<class _Ty, size_t N1,
    class _Other, size_t N2> inline
        bool operator!=(const FixedBuffAllocator<_Ty, N1>&, const FixedBuffAllocator<_Other, N2>&)
    { return N1!=N2; }
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[7]: Нет уж, позвольте!
От: senglory  
Дата: 01.08.07 21:13
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>McSeem2 wrote:


C>Кстати, у нас в постановке проекта так и звучало: "Переделать прототип

C>приложения c C# на С++" Между строчками читалось: "Эта <пиииииии>
C>программа на C# не может делать ни <пииииииииии>. Сделайте нам нормальную."

Может это, того, проектную команду надо было поменять, а не язык? Потому как 99% ПО можно писать на чем угодно — разница т-ко в скорости разработки.
Re[8]: Нет уж, позвольте!
От: VGn Россия http://vassilsanych.livejournal.com
Дата: 05.08.07 03:14
Оценка:
S>Может это, того, проектную команду надо было поменять, а не язык? Потому как 99% ПО можно писать на чем угодно — разница т-ко в скорости разработки.

За это время могли уже 3 раза поменять
... << RSDN@Home 1.2.0 alpha rev. 677>>
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.