Re[11]: История одной оптимизации
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 31.10.05 16:15
Оценка:
Здравствуйте, VladD2, Вы писали:

E>> Ведь в каждом языке есть примитивные приемы для повышения/понижения производительности на элементарном уровне. Например, в C++ возврат сложных объектов или передача их в качестве аргументов по значению -- очень дорогая операция. Например, функция, которая получает по значению пяток std::string и возвращающая std::string может серьезно просадить производительность. Самый простой выход -- использовать std::string & или const std::string &.


VD>Извини, но это очередная бредятина про оптимизацию. В стандарте С++для std::string описывается только интерфейс. Реализация же может быть любая.


Ок. Смотрим тесты производительности (тест программы в низу сообщения).

Visual C++ 7.1 (родной STL).
references_only duration: 0.062
refereces_args_value_return duration: 3.875
all_values duration: 15.218


Borland C++ 5.6 (насколько я знаю, STLPort).
references_only duration: 0.063
refereces_args_value_return duration: 3.031
all_values duration: 12.703


Digital Mars C++ 8.42n (STLPort).
references_only duration: 0.11
refereces_args_value_return duration: 2.656
all_values duration: 11.016


GNU C++ v.3.4.4 Cygwin.
references_only duration: 0.141
refereces_args_value_return duration: 4.453
all_values duration: 17.422


GNU C++ v.3.3.4 Linux
references_only duration: 0.08
refereces_args_value_return duration: 0.88
all_values duration: 3.08


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


E>> В подавляющем большинстве случаев это уже даст необходимый прирост производительности.


VD>Как раз в подавляющем большинстве случаев — это ничено не даст. Ну, кроме глупой самоуверенности тому кто это делает.


Итак, ты пытаешься утверждать что передача объекта по значению, с вызовом конструкторов и деструкторов в большинстве случаев будет настолько же эффективно, как передача ссылки на объект? Это только если конструктор и декструктор будут тривиальными, а объекты будут содержать не более одного атрибута.

Вообще Влад, ты в последнее время делаешь такие заявления, после которых я начинаю сомневаться, что ты вообще хорошо программировал на C++.




Тест производительности при передачи std::string в качестве аргументов и возвращаемого значения:
#include <iostream>
#include <string>
#include <ctime>

using namespace std;

const unsigned int iterations = 10000000;

template< class R, class T1, class T2, class T3 >
struct    meter_t
    {
        typedef R (*pfn_t)( T1 a, T2 b, T3 c );

        pfn_t    m_pfn;

        const std::string &    m_a;
        const std::string &    m_b;
        const std::string &    m_c;

        meter_t( pfn_t pfn,
                const std::string & a,
                const std::string & b,
                const std::string & c )
            :    m_pfn( pfn )
            ,    m_a( a )
            ,    m_b( b )
            ,    m_c( c )
            {}

        void
        operator()( const std::string & method_name )
            {
                std::cout << method_name << " " << std::flush;

                std::clock_t start = std::clock();

                for( unsigned int i = 0; i != iterations; ++i )
                    (*m_pfn)( m_a, m_b, m_c );

                std::clock_t finish = std::clock();

                std::cout << "duration: "
                        << double( finish - start ) / CLOCKS_PER_SEC
                        << std::endl;
            }
    };

template< class R, class T1, class T2, class T3 >
meter_t< R, T1, T2, T3 >
meter( R (*pfn)( T1, T2, T3 ),
    const std::string & a,
    const std::string & b,
    const std::string & c )
    {
        return meter_t< R, T1, T2, T3 >( pfn, a, b, c );
    }

const std::string &
references_only(
    const std::string & a,
    const std::string & b,
    const std::string & c )
    {
        return a;
    }

std::string
refereces_args_value_return(
    const std::string & a,
    const std::string & b,
    const std::string & c )
    {
        return a;
    }

std::string
all_values(
    std::string a,
    std::string b,
    std::string c )
    {
        return a;
    }

int main() 
{ 
    const std::string a = "Long long time ago...";
    const std::string b = "...in far far galaxy...";
    const std::string c = "...test for std::string perfomance...";

    meter( &references_only, a, b, c )( "references_only" );
    meter( &refereces_args_value_return, a, b, c )( "refereces_args_value_return" );
    meter( &all_values, a, b, c )( "all_values" );
}
... << RSDN@Home 1.1.4 stable rev. 510>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[12]: История одной оптимизации
От: VladD2 Российская Империя www.nemerle.org
Дата: 31.10.05 16:19
Оценка:
Здравствуйте, eao197, Вы писали:

E>А чего тут подробнее? Я уже несколько раз об этом говорил. Ты привел в качестве примера свой опыт на тот момент, когда ты и программировать-то нормально не умел (по твоим же словам). А следовательно (для меня лично) -- грош цена этому опыту.


Опыт есть опыт. Просто бессмысленно его оценивать по тому чей это опыт. Да и не причем там умение программировать.

E>Да и ты сам сказал:

E>

E>Вообще-то я говорил о другом. Я говорил, о том, что надо знать что делашь, и не делать ничего просто так.

E>Так вот, делая вторую или третью программу в своей жизни, сложно знать "что делаешь".

Об этом и говорилось в рассказе.

E>Ну об этом мы уже говорили.


Ага. Но бестолку.

E>Не так уж и долго MC разрабатывал OS/2. Уже OS/2 2.0 IBM доделывала без MC, а уж OS/2 3.0 и OS/2 4.0 были сделаны вообще без МС.


Да, да. Не долго. Ровно от начала и до момента когда МС понял бесперспективность ее развитя.
Короче МС ее создал. И этим все сказано.

VD>> Так вот в МС поняли, что OS/2 не является продуктом который требует рынок. Другими совами OS/2 не оптимальна для пользователя. Тогда МС начала разработку NT. NT оказался продуктом бескомпромисным, в отличии от OS/2 и намного более перспективным, но на то время NT была еще более неприемлема для пользователей. Тогда МС создала проект Чикаго (будующую Вынь 95). Его суть была скрещивание Windows 3.11 и Windows NT. Зазача быал — впихнуть максимум возможностей NT в ОС имеющюю намного меньшие потребности в ресустах и намного большую совместимось с 16-битным миром. Главное что пропихнул МС в Чикагу — это Win32 ATI. Конечно существовал Win32S, но в нем было реализовано уж очень мало нужных вещей. Причем и те что были реализованы — эмулировались. Второе по важности было введение изолированных адресных пространств. Для императивных языков того поколения это было очень важное нововведение. Дале шли многопоточность и красивый UI.


E>Так об этом я и говорил.


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

E> Обе корпорации хотели сделать продукт следующего уровня для PC. Только MC отталкивалась от нужд пользователей и поэтому смогла привлечь к себе разработчиков ПО.


Это так.

E>А вот IBM, видимо, расчитывала на стройность архитектуры, но нужды пользователей были им фиолетовы.


А это не так. Небыло в Полуоси никакой стройности архитекруры. Полуось, как и Вынь95 была компромисом. Причем многопараметрическим. И в определении важности приоритетов IBM координально ошиблась.

E> Уж не знаю как, но IBM не удалось привлечь разработчиков ПО.


Ну, почему же? До появления 95-ых и NT очень многие разработчики перепрыгнули на Полуось. Причем некоторые так привязались к ней, что стали откровенными ее фанатами. Другое дело, что при наличии более привлекатльной ОС только фанатики ее и не бросили. ОС оказалась не интересной в первую очередь для пользователей. А уж для программистов было только неудобно что АПИ этой ОС сильно отличалось от Виндовс 3.х которая в то время держала рынок.

Кстати, что до быстро бросила, то я вспоминаю как году в 1994-ом я читал документацию по MS C 6 и море ее было посвящено разработке для Полуоси 1.х. А вот СДК для виндовс там небыло. Так что МС довольно долго смотрел на Полуось как на любимое детя.

E>Не надо мне-то байки про ненадежность OS/2 рассказывать. Она падала только из-за кривых драйверов (как и NT).


До некоторой версии она намертво зависала от банального метвого цикла. Даже вынь 3.1 можно было в таких случаях оживить, а Полуось — нет. В общем, снова фанатский спор. Надоело. Сравнивать NT 3.х и Полуось (особенно ранних версий) по надежности — это форменный фанатизм.

E> Ну и Watcom-овский отладчик пару раз у меня OS/2 повесил. Так что надежность Warp-а была ничуть не хуже NT.


Warp был тогда когда Полуось уже была практически на лопатках. Да и он не дотягивал до NT по надежности. Другое дело, что в NT 4 был сделан шаг назад. Но этот шаг делался в рассчете на то, что ОС завоюет хайэндный рынок где тогда нужна была быстрая 3D-крафика. В общем, очередной разумный компромис.

VD>>Извини, но это очередная бредятина про оптимизацию. В стандарте С++для std::string описывается только интерфейс. Реализация же может быть любая. Посему твоя оптимизация на некоторых библиотеках приведет к потере производительности (хотя и небольшой). Но главное она в очередной раз усложнит код.


E>ДА-А-А? Ну-ну. Примеры в студию, пожалуйста.


Примеры чего? Вот ты живой пример. Ты изучил исходники всех реализаций STL?

VD>>Например, погляди как реализован CString в MFC. Сам объект содеражит только ссылку на динамически занимаемый блок памяти. Все остальное в этом блоке. Передача CString в качестве параметра и даже возврат его из функции — это самое верное решение как с точки зрения производительности, так и с точки зрения удобства использования.


E>И многопоточности, надо полагать.


Давай еще про распределенные системы поговорим. Это тоже будет очень в тему.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[12]: История одной оптимизации
От: VladD2 Российская Империя www.nemerle.org
Дата: 31.10.05 16:27
Оценка:
Здравствуйте, eao197, Вы писали:

E>Ок. Смотрим тесты производительности (тест программы в низу сообщения).

...

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

E>Итак, ты пытаешься утверждать что передача объекта по значению, с вызовом конструкторов и деструкторов в большинстве случаев будет настолько же эффективно, как передача ссылки на объект? Это только если конструктор и декструктор будут тривиальными, а объекты будут содержать не более одного атрибута.


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

E>Вообще Влад, ты в последнее время делаешь такие заявления, после которых я начинаю сомневаться, что ты вообще хорошо программировал на C++.


А С++ тут не причем. Более того, я вообще не буду использовать std::string так как он попросту не удобен. Я говорю опять же о твоих предположениях.


E>Тест производительности при передачи std::string в качестве аргументов и возвращаемого значения:

...
Кстати, читается ужасно. Неужели по проще нельзя?
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[13]: История одной оптимизации
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 31.10.05 16:32
Оценка:
Здравствуйте, VladD2, Вы писали:

E>>А вот IBM, видимо, расчитывала на стройность архитектуры, но нужды пользователей были им фиолетовы.


VD>А это не так. Небыло в Полуоси никакой стройности архитекруры. Полуось, как и Вынь95 была компромисом. Причем многопараметрическим. И в определении важности приоритетов IBM координально ошиблась.


Ты то откуда знаешь? Ты что, под OS/2 работал или программировал?

E>> Уж не знаю как, но IBM не удалось привлечь разработчиков ПО.


VD>Ну, почему же? До появления 95-ых и NT очень многие разработчики перепрыгнули на Полуось. Причем некоторые так привязались к ней, что стали откровенными ее фанатами. Другое дело, что при наличии более привлекатльной ОС только фанатики ее и не бросили. ОС оказалась не интересной в первую очередь для пользователей.


Потому, что софт под нее не разрабатывался.

VD> А уж для программистов было только неудобно что АПИ этой ОС сильно отличалось от Виндовс 3.х которая в то время держала рынок.


А вот это причина, по которой софт под OS/2 не разрабатывался. Да еще и потому, что MS лучше своих клиентов обхаживала. В частности, смогла заинтересовать производителей аппаратуры в первую очередь выпускать драйвера под Windows. Что в скором времени привело к тому, что OS/2 можно было заставить работать далеко не на всем железе.

VD>Кстати, что до быстро бросила, то я вспоминаю как году в 1994-ом я читал документацию по MS C 6 и море ее было посвящено разработке для Полуоси 1.х. А вот СДК для виндовс там небыло. Так что МС довольно долго смотрел на Полуось как на любимое детя.


E>>Не надо мне-то байки про ненадежность OS/2 рассказывать. Она падала только из-за кривых драйверов (как и NT).


VD>До некоторой версии она намертво зависала от банального метвого цикла.


До каких версий? Я с 3.0 начал под OS/2 работать и не было такого.

E>> Ну и Watcom-овский отладчик пару раз у меня OS/2 повесил. Так что надежность Warp-а была ничуть не хуже NT.


VD>Warp был тогда когда Полуось уже была практически на лопатках. Да и он не дотягивал до NT по надежности.


Вот только не надо. По ресурсоемкости Warp делал Windows (любой) только так (я помню как на 386 с 4Mb крутилась OS/2 Warp в TShell-е и свободно позволяла в первый Doom играть, и держать рядом несколько сессий с MultiEdit-ом). А надежность у него была на уровне NT.

VD>>>Извини, но это очередная бредятина про оптимизацию. В стандарте С++для std::string описывается только интерфейс. Реализация же может быть любая. Посему твоя оптимизация на некоторых библиотеках приведет к потере производительности (хотя и небольшой). Но главное она в очередной раз усложнит код.


E>>ДА-А-А? Ну-ну. Примеры в студию, пожалуйста.


VD>Примеры чего? Вот ты живой пример. Ты изучил исходники всех реализаций STL?


А причем здесь исходники? Об этом даже здавый смысл говорит: передача объекта по значению -- это вызов конструктора и деструктора. Если std::string сделан на основе подсчета ссылок, то конструктор должен сделать, по крайней мере, один инкремент. А деструктор -- один декремент. Даже если эти два действия заинлайнятся -- все равно это будет дольше, чем передать аргумент по ссылке.
... << RSDN@Home 1.1.4 stable rev. 510>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[13]: История одной оптимизации
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 31.10.05 16:36
Оценка:
Здравствуйте, VladD2, Вы писали:

E>>Ок. Смотрим тесты производительности (тест программы в низу сообщения).

VD>...

VD>Здорово. Вот теперь ты можешь утверждать о протестированных версиях библиотеки, то что на них выигрышь есть.


Его просто не может не быть
Это почти как законы физики.

E>>Итак, ты пытаешься утверждать что передача объекта по значению, с вызовом конструкторов и деструкторов в большинстве случаев будет настолько же эффективно, как передача ссылки на объект? Это только если конструктор и декструктор будут тривиальными, а объекты будут содержать не более одного атрибута.


VD>Нет. Я говорю, о том, что такие оптимизации как повсеместная передеча сторк по ссылке вряд ли приведет к заметному ускорению работы приложения. Хотя если это сделать в узких местах, то несомненно.


Приведет обязательно. Доказано практикой.

E>>Тест производительности при передачи std::string в качестве аргументов и возвращаемого значения:

VD>...
VD>Кстати, читается ужасно. Неужели по проще нельзя?

Куда же проще? Один обобщенный класс для замера производительности и три тестируемых функции.
Не сложнее твоего примера: Re[25]: Об эффективности программ
Автор: VladD2
Дата: 31.10.05

... << RSDN@Home 1.1.4 stable rev. 510>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[3]: История одной оптимизации
От: Nickolay Ch  
Дата: 31.10.05 17:30
Оценка: +1
VD>Снимаю шляпу перед Pavl-ом Dvorkin-ым. При всем моем несогласии с его мировозрением, писать он умеет убедительнее. Даже те кто, как оказалось, скорее стоит на одних позициях со мной поддержали его зажигательные речи.

Такие "зажигательные речи" произносит чуть ли не каждый первый преподаватель по программированию в ВУЗЕ. Есть, конечно, исключения, но таких единицы. Это вбивается в голову людям в течении всего обучения, естественно, многие поддержат такое мнение. А все от того, что образование просто не поспевает за темпами развития отрасли. Ну не век сейчас процессоров, "в которые можно войти".
ЗЫ Сорри за офтоп, можем отдельно обсудить проблемы преподавания программирования в российских вузах, вроде даже обсуждалось уже..
Re[4]: История одной оптимизации
От: Lloyd Россия  
Дата: 31.10.05 17:38
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>За повторение глупости.


И в чем же она заключалась?
... << RSDN@Home 1.1.4 stable rev. 510>>
Re[14]: История одной оптимизации
От: VladD2 Российская Империя www.nemerle.org
Дата: 31.10.05 18:47
Оценка:
Здравствуйте, eao197, Вы писали:

E>Ты то откуда знаешь? Ты что, под OS/2 работал или программировал?


А как же! Ты меня уже совсем за мальчика держишь.

E>Потому, что софт под нее не разрабатывался.


Да его в то время и под виндвос не дофига разрабатывалось. Софт для бизнеса жил под ДОС.

Кстати, мы думали писать код для полуоси, но воврмемя спохватились и передумали.

E>А вот это причина, по которой софт под OS/2 не разрабатывался.


Вряд ли. Если бы был рынок, то и разработки были бы.

E> Да еще и потому, что MS лучше своих клиентов обхаживала. В частности, смогла заинтересовать производителей аппаратуры в первую очередь выпускать драйвера под Windows. Что в скором времени привело к тому, что OS/2 можно было заставить работать далеко не на всем железе.


Хм. Что-то ты путашь. Драйверы под Windows были практически не нужны. Windows спокойно использовала ДОС-овские дрова (причем даже 95-ая). Это, кстати, и привело к тому, что на Windows перепрыгнуло много народа. У Полуоси с этим были большие проблемы. Родные дрова под Windows стали появляться ближе к 1995-му году и это явилось следствием признания ОС пользователями.

Кстати, многие до сих пор не считают Windows 3.х ОС. Типа оболочка над ДОС. Типа убогость. А ведь это позволило завоевать рынок.

E>До каких версий? Я с 3.0 начал под OS/2 работать и не было такого.


От это не помню. В Вынь вс. Линь ссылка была, но перерывать это барахло я не стану. Но что зависала я точно помню. Сам ее вешал. А ведь даже для 95-ых это пустяк.

VD>>Warp был тогда когда Полуось уже была практически на лопатках. Да и он не дотягивал до NT по надежности.


E>Вот только не надо. По ресурсоемкости Warp делал Windows (любой) только так (я помню как на 386 с 4Mb крутилась OS/2 Warp в TShell-е и свободно позволяла в первый Doom играть, и держать рядом несколько сессий с MultiEdit-ом). А надежность у него была на уровне NT.


Хм... Странно ты отвечашь. Я про надежность, ты про ресурсоемкость.
Ну, да и ресурсоемкость чистая не правда. Windows 3.1 жила на 2-х метрах памяти. 3.0 вообще на 640 Кб. Windows 95 жила на 4 метрах (я даже умудрился из под нее Дум 2 запустить, а ведь он сам 4 метра требовал), а на 8 просто летала с несколькими приложениями и сетью. Полуось, даже 2.х в 8 метрах только начинала работать. Запуст Windows из под Полуоси уже приводил к проблемам на 8 метрах. А для 95-ых 16-ти бытные приложения были как родные.

8 же метов по тем временам была нехилая цифра. Ну, а когда память подешевела, то 95-ые уже захватили рынок, да и NT начала пробивать себе дорогу. Все же NT тоже жила на 8 метрах, а на 16 уже даже неплохо себя чувствовала.

VD>>Примеры чего? Вот ты живой пример. Ты изучил исходники всех реализаций STL?


E>А причем здесь исходники?


При том что это завист от реализации.

E> Об этом даже здавый смысл говорит: передача объекта по значению -- это вызов конструктора и деструктора.


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

E> Если std::string сделан на основе подсчета ссылок, то конструктор должен сделать, по крайней мере, один инкремент. А деструктор -- один декремент. Даже если эти два действия заинлайнятся -- все равно это будет дольше, чем передать аргумент по ссылке.


Это ловля блох. Бестолку так рассуждать. Ты поймашь 1000 совершенно не важных для производительности приложения мест с микро-тормозами, но действительно слабые места не заметишь.

Если бы использование std::string могло что-то дать по сравнению с CString, то никто последним бы не пользовался бы.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[14]: История одной оптимизации
От: VladD2 Российская Империя www.nemerle.org
Дата: 31.10.05 18:47
Оценка: -1
Здравствуйте, eao197, Вы писали:

E>Его просто не может не быть

E>Это почти как законы физики.

Это очередное предположение с обощением. Которое не верно в общем случае.

VD>>Нет. Я говорю, о том, что такие оптимизации как повсеместная передеча сторк по ссылке вряд ли приведет к заметному ускорению работы приложения. Хотя если это сделать в узких местах, то несомненно.


E>Приведет обязательно. Доказано практикой.


Ссылки на статистику, плиз.

E>Куда же проще? Один обобщенный класс для замера производительности и три тестируемых функции.


Да уж. Больше некуда. Хотя main() вроде так ничего читается.

Кстати, зачем вообще понадобился обобщенный класс для замера производительности? Чем банальные вызовы функциий провинилис?

E>Не сложнее твоего примера: Re[25]: Об эффективности программ
Автор: VladD2
Дата: 31.10.05

E>

Да, нет. Сильно сложнее. Там логика прямая и простая. Да и тест там сложнее.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: История одной оптимизации
От: VladD2 Российская Империя www.nemerle.org
Дата: 31.10.05 18:47
Оценка:
Здравствуйте, Nickolay Ch, Вы писали:

NC>А все от того, что образование просто не поспевает за темпами развития отрасли. Ну не век сейчас процессоров, "в которые можно войти".


Дык вот тот же Dvorkin вроде как даже пытается новое изучить. Но вот получается чистешая онтипатия, так как притят сами приципы заложенные в основу платформы. Как может показаться интересным новое если оно отвергает такие принципы как реинтерпретация памити, возню с указателями, а в добавок еще и навязывает абстрации и ОО-стиль программирования?

NC>ЗЫ Сорри за офтоп, можем отдельно обсудить проблемы преподавания программирования в российских вузах, вроде даже обсуждалось уже..


Вроде уже пробовали. Количество мнений было вообще необозримым.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[15]: История одной оптимизации
От: Cyberax Марс  
Дата: 31.10.05 19:07
Оценка: 6 (1) +1
VladD2 wrote:

> Это ловля блох. Бестолку так рассуждать. Ты поймашь 1000 совершенно не

> важных для производительности приложения мест с микро-тормозами, но
> действительно слабые места не заметишь.

Я смог ускорить одно свое приложение на 25% после замены std::string на
flex_string с правильными политиками.

Потом я написал свой велосипедный класс строк (с поддержкой move
constructors) и ускорил все еще в два раза.

> Если бы использование std::string могло что-то дать по сравнению с

> CString, то никто последним бы не пользовался бы.

CString исопльзуют потому, что он поддерживается в MFC/ATL.

--
С уважением,
Alex Besogonov (alexy@izh.com)
Posted via RSDN NNTP Server 1.9
Sapienti sat!
Re[15]: История одной оптимизации
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 01.11.05 05:20
Оценка:
Здравствуйте, VladD2, Вы писали:

E>>Куда же проще? Один обобщенный класс для замера производительности и три тестируемых функции.


VD>Да уж. Больше некуда. Хотя main() вроде так ничего читается.


VD>Кстати, зачем вообще понадобился обобщенный класс для замера производительности? Чем банальные вызовы функциий провинилис?


Последствия copy-paste. Я этот тест не с нуля делал, а взял готовый, в котором этот functor уже был.
... << RSDN@Home 1.1.4 stable rev. 510>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[5]: История одной оптимизации
От: Кузнецов Денис Викторович Казахстан  
Дата: 01.11.05 05:45
Оценка: 1 (1) +1
Здравствуйте, VladD2, Вы писали:

VD>Логичнее? Не факт.


К сожалению в данном случае твое мнение учитываться не будет, поскольку ты сам являешсья субъектом оценки. Сами для себя мы всегда белые и пушистые. А вот для других...

И вообще, извини за критику, я в этом форуме по большей части читатель, но вот какое дело. Ты модератор, а это по идее должно накладывать на человека определенную ответственность. Не так ли? Я не в коей мере не пытаюсь мораль читать, просто когда в форуме один из самых больших спорщиков модератор — то даже читать тяжко бывает становится. И никто урезонить тебя иногда не может. Худо.

P.S. Назрело, еще раз прошу извинения.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[15]: История одной оптимизации
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 01.11.05 06:17
Оценка:
Здравствуйте, VladD2, Вы писали:

Спасибо за внезапную holy war OS/2 vs Windows
Хоть каждый и остался при своем мнении, но вспомнить молодость было приятно.

E>> Об этом даже здавый смысл говорит: передача объекта по значению -- это вызов конструктора и деструктора.


VD>Вот только не надо апеллировать к зравому смыслу. Я как раз вижу его отсуствие в подобных рассуждениях. Объекты объектам рознь. Я уже приводил пример CString который только проигрывает при передаче по ссылке.


А ты уверен, что CString проигрывает от передачи по ссылке?
references_only duration: 0.093
refereces_args_value_return duration: 0.735
all_values duration: 2.437

код теста внизу сообщения.

Все-таки со здравым смыслом спорить сложно. Да и вряд ли полезно.

Кроме того, я не зря вначале говорил про многопоточность. Реализации std::string, основанные на подсчете ссылок и copy on write, в многопоточных приложениях имеют скрытый оверхед: скопированная в другую нить строка при первом обращении к ней на изменение будет останавливать нить для синхронизации с исходной строкой. Поэтому reference counting реализации дают выигрыш при копировании, но проигрывают его обратно при изменении строки.

E>> Если std::string сделан на основе подсчета ссылок, то конструктор должен сделать, по крайней мере, один инкремент. А деструктор -- один декремент. Даже если эти два действия заинлайнятся -- все равно это будет дольше, чем передать аргумент по ссылке.


VD>Это ловля блох. Бестолку так рассуждать. Ты поймашь 1000 совершенно не важных для производительности приложения мест с микро-тормозами, но действительно слабые места не заметишь.


Вот здесь у меня другое мнение. 1000 мест, каждое из которых дает проигрыш 0.002% (малая величина, не так ли), в сумме дадут 2% прироста производительности. За просто так заметь.

Ну и обрати внимание на разрыв в тестах между references_only и all_values. Разница в 26 раз для тебя кажется мелочью?

VD>Если бы использование std::string могло что-то дать по сравнению с CString, то никто последним бы не пользовался бы.


А я CString и не пользуюсь. Им пользуются только те, кто был вынужден на MFC/ATL/WTC под Windows программировать.




Текст программы для измерения оверхеда при передаче CString.
#include "stdafx.h"

#include <iostream>
#include <string>
#include <ctime>

using namespace std;

const unsigned int iterations = 10000000;

template< class R, class T1, class T2, class T3 >
void
meter(
    const std::string & method_name,
    R (*pfn)( T1, T2, T3 ),
    const CString & a,
    const CString & b,
    const CString & c )
    {
        std::cout << method_name << " " << std::flush;

        std::clock_t start = std::clock();

        for( unsigned int i = 0; i != iterations; ++i )
            (*pfn)( a, b, c );

        std::clock_t finish = std::clock();

        std::cout << "duration: "
                << double( finish - start ) / CLOCKS_PER_SEC
                << std::endl;
    }

const CString &
references_only(
    const CString & a,
    const CString & b,
    const CString & c )
    {
        return a;
    }

CString
refereces_args_value_return(
    const CString & a,
    const CString & b,
    const CString & c )
    {
        return a;
    }

CString
all_values(
    CString a,
    CString b,
    CString c )
    {
        return a;
    }

int main() 
{ 
    const CString a = "Long long time ago...";
    const CString b = "...in far far galaxy...";
    const CString c = "...test for std::string perfomance...";

    meter( "references_only", &references_only, a, b, c );
    meter( "refereces_args_value_return", &refereces_args_value_return, a, b, c );
    meter( "all_values", &all_values, a, b, c );
}
... << RSDN@Home 1.1.4 stable rev. 510>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[3]: История одной оптимизации
От: Nickolay Ch  
Дата: 01.11.05 11:37
Оценка:
VD>Да, я скорее не неуважительно. Я скорее раздражительно. Возможно я тут не прав и перегибаю плаку. Однако я искренне считаю, что такая безрассудная борьба за производительность исходящая от преподавателя крайне деструктивно скажется на его учениках. Свобода слова и свобода после слова несомненно незыблема. Но это до тех пор пока речь идет о твоем личном мнении. Как только ты начинашь учить других, то твое мнение превращается в инструмент воспитания. Ведь ты отвественнен за то что будет в головах твоих учеников. И если неподготовленные головы пропаласкать вот такими залихватскими речами о производительности, то практически гарантированно можно получить людей которые просто не в состоянии будут понять, что такое грамотное проектирование, так как их учитель им обяснил, что словами о грамотном проектировании обычно прикрывают неумение и не желание писать оптимальный код. Ну, а если это еще смазать твоими рассуждениями об индусах... Кому же хочется быть поставленным в один ряд с индусами?

Вот за это жирный плюс.

ЗЫ. Опыт — очень абстрактная и расплывчатая категория. Опыт опыту рознь.
В данной тематике актуален конкретно программерский опыт(а технологии меняются очень динамично).
Не общежизненный(кстати, и в такой не верю).
Re[5]: История одной оптимизации
От: Nickolay Ch  
Дата: 01.11.05 11:44
Оценка: +1
VD>Дык вот тот же Dvorkin вроде как даже пытается новое изучить. Но вот получается чистешая онтипатия, так как притят сами приципы заложенные в основу платформы. Как может показаться интересным новое если оно отвергает такие принципы как реинтерпретация памити, возню с указателями, а в добавок еще и навязывает абстрации и ОО-стиль программирования?

Вообщето и GC, и ооп, и абстракции — далеко не новые идеи, а очень даже старые по меркам существования индустрии. Если подходить к делу с идейной точки зрения, а не с прагматической, имхо, ничего хорошего не будет ни от нового, ни от старого. Это как бы от мировоззрения чтоль зависит уже. Хотя есть конечно привычки к тому, что уже хорошо знаешь.
Мне ни в этой, ни в соседнем треде так и не дали четокго ответа на вопрос: "ради чего проводить битовыжимание, изобретать велосипеды, отказываться от удобных механизмов и библиотек". По крайней мере, внятного ответа не услышал.
Re[6]: История одной оптимизации
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 01.11.05 12:01
Оценка:
Здравствуйте, Nickolay Ch, Вы писали:

NC>Мне ни в этой, ни в соседнем треде так и не дали четокго ответа на вопрос: "ради чего проводить битовыжимание, изобретать велосипеды, отказываться от удобных механизмов и библиотек". По крайней мере, внятного ответа не услышал.


Ради того, чтобы программа работала в заданных условиях. Например, SIM Toolkit апплет должен умещаться в 16Kb SIM карточку. Правильная, полностью функциональная версия занимает 19Kb. Нужно как-то "похудеть" апплет на 3Kb.

Такой пример подойдет?
... << RSDN@Home 1.1.4 stable rev. 510>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[6]: История одной оптимизации
От: FR  
Дата: 01.11.05 12:14
Оценка: -2
Здравствуйте, Nickolay Ch, Вы писали:

NC>Мне ни в этой, ни в соседнем треде так и не дали четокго ответа на вопрос: "ради чего проводить битовыжимание, изобретать велосипеды, отказываться от удобных механизмов и библиотек". По крайней мере, внятного ответа не услышал


Вы тоже перегибаете палку с заявлениями о ненужности оптимизации, пока еще (и это пока продлится похоже неопределенно долго) полно задач в которых битовыжимание необходимо. А красивая архитектура и оптимизация не антиподы, очень часто это вещи совершенно независимые.
Re[7]: История одной оптимизации
От: Andrei N.Sobchuck Украина www.smalltalk.ru
Дата: 01.11.05 12:52
Оценка: 24 (2) -1
Здравствуйте, FR, Вы писали:


FR> А красивая архитектура и оптимизация не антиподы, очень часто это вещи совершенно независимые.


"Не красивые самолёты не летают". Красота это, в первую очередь, мерило функциональности. Соответсвенно "некрасивая программа" это когда в ней что-то не так. Если кто-то считает красивой тормозную программу, то такой человек только тормозные программы и может делать. Потому что это его понимание "правильности".
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Я ненавижу Hibernate
Автор: Andrei N.Sobchuck
Дата: 08.01.08
!
Re[16]: История одной оптимизации
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.11.05 14:27
Оценка:
Здравствуйте, eao197, Вы писали:

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


E>Спасибо за внезапную holy war OS/2 vs Windows

E>Хоть каждый и остался при своем мнении, но вспомнить молодость было приятно.

Это тебе спасибо ты же ее к ночи упомянул.

E>А ты уверен, что CString проигрывает от передачи по ссылке?


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

E>
E>references_only duration: 0.093
E>refereces_args_value_return duration: 0.735
E>all_values duration: 2.437
E>

E>код теста внизу сообщения.

Вообще, логично. Там же все же вызывается конструктор/деструктор. Действительно тут ты прав, для С++, передача некоторых объектов по значению может быть медленее. Хотя опять таки есть POD-ы, да и инлайнинг иногда рулит. В твоме тесте инлайнинга быть не может (указатель на функцию как ни как).
А, например, разные POINT-ы передавать по ссылке только время терять.

E>Кроме того, я не зря вначале говорил про многопоточность. Реализации std::string, основанные на подсчете ссылок и copy on write, в многопоточных приложениях имеют скрытый оверхед: скопированная в другую нить строка при первом обращении к ней на изменение будет останавливать нить для синхронизации с исходной строкой. Поэтому reference counting реализации дают выигрыш при копировании, но проигрывают его обратно при изменении строки.


Ерунду говоришь. Скопированная строка есть скопированная строка. А если ты ее без копирования передашь (по ссылке), то в любом случае потребуется синхронизация. Так что разница тут только в семантике копирования.

Создание глобальных строк вообще не разумный выход в многопоточном приложении. А в рамках потока проблем сней не будет.

Для многопоточности конечно хорошо прменять имьютебл-кобъекты, но в С++ с ними беда. За пару секунд можно плучить ссылку и делать все что хочешь.

E>Вот здесь у меня другое мнение. 1000 мест, каждое из которых дает проигрыш 0.002% (малая величина, не так ли),


Величина высосаная из пальца. Не так ли?

E> в сумме дадут 2% прироста производительности. За просто так заметь.


Только к пакетным приложениям применима матрика "общая производительность". Для всех остальных она смысла не имеет. Для них унжно говорить о пиковой производительности в узких местах. Все твои 2, и даже 22 процента ровном счетом ничего не будут значит.

Простой пример, если я пишут дрэг-дроп для некого контрола, то мне совершенно все равно сколь эффектинво я работаю со стороками. Ведь я обрабатываю мизерное их число. Время же у меня регламентируется очщущениями пользовтеля. Человек ощущает тормоза когда не чувствует отклика в диапазоне 0.3 секунды. Эта цифра может варьироваться от 0.1 до 0.5 в завимимости от тормознутости пользователя и инерции девайсов которые он использует. Так вот все что успевает произойти в эти 0.1-0.3 секунды для человека выглядит как просходящее мгновенно. И я тебе гарантирую, что десяток переданных по значению строк ни на что ровным счетом не повлияют.

Повлиять же неэффектиная передача объектов может только при одном условии. Если эта передача делается очень большое количество раз в узком мете приложения. Вывод — нужно обращать внимание именно на узкие места.

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

E>Ну и обрати внимание на разрыв в тестах между references_only и all_values. Разница в 26 раз для тебя кажется мелочью?


Кажется. В узких местах конечно такого допускать нельзя. Но вот в каком-нибудь MessageBox и т.п. без проблем. Это ровны счетом ничему не повредит.

VD>>Если бы использование std::string могло что-то дать по сравнению с CString, то никто последним бы не пользовался бы.


E>А я CString и не пользуюсь. Им пользуются только те, кто был вынужден на MFC/ATL/WTC под Windows программировать.


Что значит "был вынужден"? MFC/ATL — это библиотеки нехило упрощающие разработку приложений под Виндвос. Тот же CString намного удобнее уродца из СТЛ. Это как раз его скорее используют по нужде.


ЗЫ

Погляди на свой тест. На 10 000 000 итераций (по буквам — десять миллионов итераций!) на моей машине уходит в худшем случае 1.5 секунды, т.е. 1500 милесекунд. То есть стоимость одного вызова == 0.00015 милисекунды, или 0.15 микросекунды. Из них 0.03 микросекунды уходит на сам вызовов, и только 1.2 на передачу 3-х параметров и возврат еще одного значения.

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

Так что передавать строковый класс по константной ссылке явно полезно, но вероятность того, что это приведет к серьезному увеличению производительности всегоп риложения я бы оценил скепрически. Конечно если это, например, компилятор, или парсер ХМЛ-я, то безусловно он значительно ускорится. Но если это, например, десктоп прилоежине, то это скорее всего ничего не даст.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.