LINUX.ORG.RU

Один из лучших компиляторов C++ для Linux прекращает существование


2

0

Один из лучших компиляторов С++ для Linux, KAI C++, прекращает свое существование с 30 апреля 2002 года, через два года после покупки Kuck & Accociates Inc. компанией Intel. 30 апреля будут прекращены продажи, поддержка и исправление ошибок в существующих релизах будут продолжаться до конца 2003 года. Технологии KAI будут интегрированы в компиляторы Intel. В настоящее время компиляторы Intel уступают KAI как по уровню совместимости со стандартом, так и по возможностям оптимизации.

>>> Подробности



Проверено:

Ответ на: комментарий от gns

Кстати про криптографию - реализация всяких там DES-ов да RSA на OCaml по скорости почти не отличалась от Си. Подробности см. где-то в hump.

anonymous
()

2YePhIcK: "А вообще, именно этот вариант решения я сейчас продумываю для следующего этапа оптимизации, так что я рад, что не я один считаю этот путь правильным ;) "

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

"Я бы, всё же, сделал две отдельный функции. Даже (если дизайн потребует) виртуальные. Потому что перевод целых чисел в 10-й и 8-й формат оптимизируется кардинально разными способами. Каждую цифру восьмиричного числа можно очень даже быстро получить битовым смещением и маской :). Для десятичного же этот метод наприменим в принципе "

Зависит от вероятности появления восьмеричных чисел. Если на выходе смесь из десятичных и восьмеричных чисел, где восьмеричных пренебрежимо мало, то почему бы и нет: один цикл и if заменяется на пару загрузок. Потом это был всего лишь пример параметризации, можно привести более удачный с шестнадцатиричными и восьмеричными числами. Указатели на функции, кстати, тоже параметризация ;)

Первые пара пунктов всего лишь игра ума, самый реальный из приведенных, на мой взгляд, только третий путь, хотя там тоже надо делать очень акуратно, не забывать о кэше инструкций и т.д. Хотя я не спец по текстовому форматингу, только по оптимизациям ;)

ZhekaSmith
()

2AC & anonemnyi

Пожалуй ты прав. Нет оверхеда. Если аккуратно.
Посыпаю голову пеплом. 
Беру все слова назад.

:((((

Но зато как я выступал!!!

Только теперь уже спрошу

Что ты предлагаешь в замен 
***U;
для трехмерного динамического массива?


Я конечно не жду ответа. Не заслужил.
Но может найдешь время.

Bear

anonymous
()

я тут попробовал 3.04 & 3.10
результаты:
P41600/PC133/2.2
gcc 2.96 | 3.04| 3.10

g++ -o glu2 test0.cc
196.233 |-| 170.54
16.823 |-| 17.06
g++ -o glu2 -O3 -mcpu=i686 test0.cc
27.9 |54.746| 27.706
2.395| 4.360| 3.901
g++ -o glu2 -O3 -march=i686 -fexpensive-optimizations -funroll-all-loops -fstrength-reduce -fomit-frame-pointer -ffast-math -finline-functions -malign-functions=4 -malign-jumps=4 -malign-loops=4 test0.cc
23.416| 39.827| 26.542
2.316 |4.607 |3.855
g++ -o glu2 -O3 -mcpu=i686 -fexpensive-optimizations -funroll-all-loops -fstrength-reduce -fomit-frame-pointer -ffast-math -finline-functions -malign-functions=4 -malign-jumps=4 -malign-loops=4 test0.cc
25.34 |-| 27.541
2.163 |-| 3.871
g++ -o glu2 -O3 -march=i686 -fforce-addr -fexpensive-optimizations -funroll-all-loops -fstrength-reduce -fomit-frame-pointer -ffast-math -finline-functions test0.cc
26.16 |-| 26.184
2.181 |-| 3.596

- что-нибудь при установке можно было сделать не так?..

P.S
time ./glu2 > time 2&1

lu_factorize:1000000 factorizations:27.616 s
lu_substitute:1000000 substitutions:3.899 s
solution:
[-2.1882,6.814,17.9642,-13.4885,-1.3628,-8.31635,-0.0227628,-0.101128,]
31.52user 0.00system 0:31.52elapsed 99%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (239major+24minor)pagefaults 0swaps

так что многозадачность особой роли не играет

Anonymous ★★★★★
()

2Bear элементарно, по аналогии с двуменым массивом, щаз все писать с нуля
лень(маевка у нас щаз в нск'е), если тебе это нужно, пошли в форум девел,
для направления мыслей приводу просто куски из поделки шкоольников :)

class Vector1D {
        double *p;
  public:
        Vector1D(double* pp) {p=pp;}
        Vector1D(const Vector1D& v) {p=v.p;}
        double& operator[](int i) {return p[i];}
        const double& operator[](int i) const {return p[i];}
};

class Array2D_base {
  protected:
        double *p;
        int n,m;
        
  public:
        Array2D_base(int n_, int m_) {
                n=n_;
                m=m_;
                p=new double[n*m];
        }
        Array2D_base(const Array2D_base& a) {
                n=a.n; 
                m=a.m; 
                p=new double[n*m]; 
                memcpy(p, a.p, n*m*sizeof(double));
        }
        Array2D_base& operator=(const Array2D_base& a) {
                if(&a==this) return *this;
                delete[] p;
                n=a.n; 
                m=a.m; 
                p=new double[n*m]; 
                memcpy(p, a.p, n*m*sizeof(double));
                return *this;
        }
        ~Array2D_base() {
                delete[] p;
        }
};

class Array2D_simple : public Array2D_base {
  public:
        Array2D_simple(int n, int m) : Array2D_base(n,m) {}

        double* operator[](int i) {return p+i*m;}
        const double* operator[](int i) const {return p+i*m;}
        
};

class Array2D_mapped : public Array2D_base {
        double **mp;
        void fillmp(int n, int m) {
                mp=new (double*)[n];
                for(int i=0; i<n; i++)
                        mp[i]=i*m+p;
        }
        
  public:
        Array2D_mapped(int n, int m) : Array2D_base(n,m) {
                fillmp(n,m);
        }
        Array2D_mapped(const Array2D_mapped& a) : Array2D_base(a.n, a.m) {
                fillmp(n,m);
                
        }
        double* operator[](int i) {return mp[i];}
        const double* operator[](int i) const {return mp[i];}
};

class Array2D_generic : public Array2D_base {
  public:
        Array2D_generic(int n, int m) : Array2D_base(n,m) {}
        Array2D_generic(const Array2D_generic& a) : Array2D_base(a.n, a.m) {}
        
        Vector1D operator[](int i) {return Vector1D(p+i*m);}
};


это школьники тестировали сей самый оверхед... можно лучше местами,
но для тестовой тривиальной реализации потянет :)

HTH

anonymous
()
Ответ на: комментарий от anonymous

2 Bear: Что ты предлагаешь в замен ***U; для трехмерного динамического массива?
Ну у нас же все зависит от конкретики, не так ли? "Редкий" массив или нет, есть ли какие "регулярности" в "расположении" его элементов, как в основном будем по этому массиву ходить -- по горизонтальным срезам, или по вертикальным, или еще как "специфически", нужен ли random access. Нужна ли нам проверки на выход за пределы массива и все такое. Дальше, в каком контексте мы решаем задачу, насколько важна производительность, какие требования к объему кода (можно ли bloat'ить инлайнингом, и т.д.), есть ли у нас время на оптимизацию. и т.д.
К примеру, нужно обрабатывать такие массивы на, скажем, pocket pc, пишем код один раз, переносимость на desktop не нужна, все должно не слишком тормозить, включаемом/выключаемой проверки индексов не нужно. Компилятор для pocket pc evc++ хреново инлайнит и почти не понимает шаблонов. Если нужен достаточно быстрый доступ по [i][j][k], и можем пожертовать немного памяти (памяти на pocket pc сейчас вагон), заворачиваем в класс размеры, float*** array, в нем определяем конструкторы (распределяем память как в numerical recipes), очистку и методы float*** data() и const float*** data() const, в алгоритмах забираем указатель и с ним работаем. Если в основном ходим по "фронтальным" или "горизонтальным" срезам, храним в column-major или depth-major форматах, определяем float** front_slice() или float** level(), оператор ()(i,j,k) для редкого случайного доступа, data() не определяем, поскольку потом по забывчивости можно разыменовать data не так и получить не тот элемент, который хотелось. Если же оверхед на данные нельзя, а по массиву ходим, к примеру, подряд по строкам, то тоже заворачиваем в класс, память распределяем один раз скопом, определяем соответствующий итератор и оператор ()(i,j,k) (или float() element(i,j,k) const, float& element(i,j,k)), который будет делать нужные умножения для random-access доступа -- такой доступ будет медленным.
если же нужно библиотечный "трехмерный массив вообще", который будут пользовать разные люди, есть хорошо оптимизирующий компилятор, который не боится ни шаблонов, ни инлайнинга, умеет оптимизировать через границы функций и все такое (например, тот же KAI), то можно определить шаблон, хранящий данные в нужном major формате (или специализации одного и того же шаблона для разных типов хранения), адаптеры, представляющие нужные "view" этого массива (по фронтальным, боковым и горизонтальым срезам) и соответствующие двумерные "подматрицы" и (одномерные) "векторы"-строки, колонки, столбцы, итераторы, позволяющие быстро перебирать массив тем или иным образом. Про оператор ()(i,j,k) написать "лучше не используйте его, а пользуйтесь итераторами и пишите ваши алгоритмы используя итераторы". Поручить написать такой шаблон кому-нибудь, написать самому или взять из blitz. Радоваться производительности на уровне чистого C или даже большей, при наличии абстракции, большей читаемости, структурированности, контроля типов и ошибок и прочих типа преимуществ.

AC
() автор топика
Ответ на: комментарий от anonymous

2 Bear: >Вижу что ответишь. ухожу умытый
что-то я вашего "стиля" не понимаю. толи обида какая-то непонятная сквозит, толи совершенно неуместная ирония. Если вы задаете мне какой-то конкретный вопрос, очевидно, что я попытаюсь на него при наличии времения ответить. Давайте или будем вести беседу в нормальном тоне, или завершим ее к такой-то матери.

AC
() автор топика

А кто нидь тестировал gcc-3.1 (g++-3.1) на предмет profile driven optimizations ?

С моей точки зрения довольно интригующая feature :) Сам бы потестировал, да времени не хватает ,) А тут вроде есть народ которому нравится performance тесты гонять ,) В общем, было бы интересно :)

--
With best wishes,
Nick.

bugfixer ★★★★
()

ну давай протестим, что и как тебе протестить? :)

пока праздники время вроде есть...

anonymous
()
Ответ на: комментарий от anonymous

> Насчет типов и шаблонов - я плохо понял твое высказывание

Это потому, что я забыл, что хотел сказать.

Эсли бы, например, пися шаблон, необходимо было указывть класс-родитель параметра, всё было бы просто. Можно было бы сгенеритьь код.

Но! Параметром шаблона может быть любой тип!

Стало быть, либо _весь_ код шаблона должен быть в .h-файле (что гораздо проще сделать макросом, имхо) -- либо таки храни коды функций отдельно и поимей геморрой с генерацией кода тел всех функций или членов... В общем, я это всё из хелпов вычитал, посмотри...

С уваением -- Смоляное Чучелко

anonymous
()
Ответ на: комментарий от anonymous

>необходимо было указывть класс-родитель параметра, всё было бы просто...Но! Параметром шаблона может быть любой тип!
1. и что в этом плохого? 2. "отсечь" нежелательные типы параметров можно с помощью concept check.
>_весь_ код шаблона должен быть в .h-файле (что гораздо проще сделать макросом, имхо)
ну не путайте шаблоны и макросы, ради бога. ведь уже десять раз пережевано, чем они отличаются.

AC
() автор топика

В тему различных языков (мне только что fortune выдала):

THE LESSER-KNOWN PROGRAMMING LANGUAGES #5: VALGOL
From its modest beginnings in Southern California's San Fernando Valley,
VALGOL is enjoying a dramatic surge of popularity across the industry.

Here is a sample program:
        LIKE, Y*KNOW(I MEAN)START
        IF PIZZA = LIKE BITCHEN AND GUY = LIKE TUBULAR AND
           VALLEY GIRL = LIKE GRODY**MAX(FERSURE)**2 THEN
                FOR I = LIKE 1 TO OH*MAYBE 100
                        DO*WAH - (DITTY**2)
                        BARF(I)=TOTALLY GROSS(OUT)
                SURE
        LIKE BAG THIS PROGRAM
        REALLY
        LIKE TOTALLY (Y*KNOW)
        IM*SURE
        GOTO THE MALL


:-)))

anonymous
()

2 anonymous (*) (2002-05-05 08:34:00.61)

Берем любой тестик. Компиляем со всеми ключами как обычно плюс -fprofile-arcs

Запускаем (в процессе генерятся файлы *.da)

Заново компиляем (теперь с -fbranch-probabilities).

Запускаем. Постим результаты ,)

--
With best withes,
Nick

bugfixer ★★★★
()
Ответ на: комментарий от AC

2 AC

>Если нужен достаточно быстрый доступ по
>[i][j][k], и можем пожертовать немного памяти (памяти на pocket pc сейчас вагон), заворачиваем в класс размеры, float*** array, в нем определяем конструкторы (распределяем
>память как в numerical recipes), очистку и методы float*** data() и const float*** data() const, в алгоритмах забираем указатель и с ним работаем. Если в основном ходим по
>"фронтальным" или "горизонтальным" срезам, храним в column-major или depth-major форматах, определяем float** front_slice() ....

Прежде чем предлагать программу действий для 20 человек на год ну прочти же
свежую книжку Страуструпа до конца 
Там есть главка про valarray, который именно для этого и был внесен в стандарт 
Очень рекомендую :)))

#include <iostream>
#include <valarray> 
#include <algorithm>


int main (int argc, char * argv[])
{const size_t lenL[] = {1, 3, 3};
 const size_t strL[] = {3*3,3, 1};
 const valarray<size_t> lengthL(lenL, 3), strideL(strL, 3);
 valarray<double> aPlaneL(3*3);
 
 gslice firstPlaneL= gslice(0, lengthL, strideL);
 valarray <double> array3x3x3 (1,3*3*3); 
 
 array3x3x3[firstPlaneL] =  0;
 array3x3x3 += 1;
 array3x3x3 *= 2;
 array3x3x3[firstPlaneL] *=  (aPlaneL=-1);

 for ( int iL= 0; iL<3; ++iL)
   {
     std::copy (&array3x3x3[iL*3*3], &array3x3x3[iL*3*3+3], ostream_iterator<double>(cout," ")); cout<<endl; 
     std::copy (&array3x3x3[iL*3*3+3], &array3x3x3[iL*3*3+3*2], ostream_iterator<double>(cout," ")); cout<<endl; 
     std::copy (&array3x3x3[iL*3*3+3*2], &array3x3x3[iL*3*3+3*3], ostream_iterator<double>(cout," ")); cout<<endl; 
     cout<<endl;
   }; //for
}; //main 

ps Ко всем тестерам C vs C++

Это по меньшей мере не серьезно компилить одну и ту же программу
на С и С++ а потом говорить кто из них быстрее.
Сначало было бы неплохо задействовать родные для С++
возможности, предназначенные для конкретной задачи. Выжать все из
тех расширений, которых нет в C. A потом и сравнивать.
Например для программы по поиску обратрой матрицы 
было бы неплохо использовать тот самый valarray :)

anonymous
()

2 AC

>Если нужен достаточно быстрый доступ по
>[i][j][k], и можем пожертовать немного памяти (памяти на pocket pc сейчас вагон), заворачиваем в класс размеры, float*** array, в нем определяем конструкторы (распределяем
>память как в numerical recipes), очистку и методы float*** data() и const float*** data() const, в алгоритмах забираем указатель и с ним работаем. Если в основном ходим по
>"фронтальным" или "горизонтальным" срезам, храним в column-major или depth-major форматах, определяем float** front_slice() ....

Прежде чем предлагать программу действий для 20 человек на год ну прочти же
свежую книжку Страуструпа до конца 
Там есть главка про valarray, который именно для этого и был внесен в стандарт 
Очень рекомендую :)))

#include <iostream>
#include <valarray> 
#include <algorithm>


int main (int argc, char * argv[])
{const size_t lenL[] = {1, 3, 3};
 const size_t strL[] = {3*3,3, 1};
 const valarray<size_t> lengthL(lenL, 3), strideL(strL, 3);
 valarray<double> aPlaneL(3*3);
 
 gslice firstPlaneL= gslice(0, lengthL, strideL);
 valarray <double> array3x3x3 (1,3*3*3); 
 
 array3x3x3[firstPlaneL] =  0;
 array3x3x3 += 1;
 array3x3x3 *= 2;
 array3x3x3[firstPlaneL] *=  (aPlaneL=-1);

 for ( int iL= 0; iL<3; ++iL)
   {
     std::copy (&array3x3x3[iL*3*3], &array3x3x3[iL*3*3+3], ostream_iterator<double>(cout," ")); cout<<endl; 
     std::copy (&array3x3x3[iL*3*3+3], &array3x3x3[iL*3*3+3*2], ostream_iterator<double>(cout," ")); cout<<endl; 
     std::copy (&array3x3x3[iL*3*3+3*2], &array3x3x3[iL*3*3+3*3], ostream_iterator<double>(cout," ")); cout<<endl; 
     cout<<endl;
   }; //for
}; //main 

ps Ко всем тестерам C vs C++

Это по меньшей мере не серьезно компилить одну и ту же программу
на С и С++ а потом говорить кто из них быстрее.
Сначало было бы неплохо задействовать родные для С++
возможности, предназначенные для конкретной задачи. Выжать все из
тех расширений, которых нет в C. A потом и сравнивать.
Например для программы по поиску обратрой матрицы 
было бы неплохо использовать тот самый valarray :)

anonymous
()
Ответ на: комментарий от anonymous

>ну прочти же свежую книжку Страуструпа до конца. Там есть главка про valarray
дядя, не учите меня жить, а лучше учитесь читать. Как научитесь и прочитаете, то увидите, что речь в моей примере шла о evc++, для которого a) в комплекте поставки нет stl, b) которого stl-ный подход с обильнымм темплэйтами и завязкой на inline убивает наповал. Незачем на таком компиляторе гонять valarray. Для нормального же компилятора он тоже не нужен, поскольку есть намного более удобные blitz и mtl. лучше бы в комитете вместо не лучшей реализации массивов внесли бы стандарт hash_map:)
>Сначало было бы неплохо задействовать родные для С++ возможности, предназначенные для конкретной задачи
Компиляторов, криво/плохо поддерживающих родные для c++ возможности вагон и маленькая тележка. Это намек.

AC
() автор топика
Ответ на: комментарий от AC

>2 Bear: >Вижу что ответишь. ухожу умытый 
>что-то я вашего "стиля" не понимаю. 
>толи обида какая-то непонятная сквозит, 
>толи совершенно неуместная ирония. 
>Если вы задаете мне какой-то конкретный вопрос, 
>очевидно, что я попытаюсь на него при наличии времения ответить.
>Давайте или будем вести беседу в нормальном тоне, 
>или завершим ее к такой-то матери.

2AC

Нет ни какой иронии. 

Мне на самом делее неприятно, что вместо конструктивного
диалога возникла перепалка.

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

А обидеть челавека почем зря это легко. 

Я приношу извинения за грубость. 

Спасибо за ответ.

К сожалению не знаю будете ли Вы читать этот тред
ибо уже дугие новости на повеске.

Хотелось бы, что бы Вы все таки прочли это письмо, и
хоть и с запозданием.

Еще раз прошу простить.
С уважением 

Bear

  

anonymous
()

2AC 

>Вижу что ответишь. ухожу умытый 

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

Я прсто увидел ответ. 

Еще раз спасибо.

Bear

anonymous
()

2AC 

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

Удачи 

Bear

anonymous
()
Ответ на: комментарий от anonymous

2 Bear: и вам удачи.
P.S.: Если я обращаюсь к кому-то конкретному с "именем", я всегда его называю.

AC
() автор топика

2AC

>Компиляторов, криво/плохо поддерживающих родные для c++ возможности вагон и маленькая тележка. Это намек.


Дурацкий вопрос:
A зачем вообще тестировать кривые/плохие компиляторы.
Кто рискнет связаться с этой гадостью, даже если она на 5-15% быстрее?
Так ведь можно повторить подвиг Билла, завесившего Windы 
прямо на их презентации всему миру :)

>для нормального же компилятора он тоже не
>нужен, поскольку есть намного более удобные blitz и mtl. 
>лучше бы в комитете вместо не лучшей реализации массивов внесли бы стандарт hash_map:) 
удобная библиотека - вещь хорошая, но стандарт есть стандарт.

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

a hast_map (hash_set) штука очень даже полезная, 
правда кое-где кривоватая:
#include <iostream> 
#include <set> 
#include <algorithm> 

int main (int argc, char * argv[])
{
  const int intsL[] = {1,2,5,7,3,4};
  std::set <int> setL;
  std::copy (intsL, intsL+sizeof(intsL)/sizeof(int), std::inserter<std::set<int> >(setL, setL.begin()));
  std::copy (setL.begin (), setL.end (), ostream_iterator<int>(cout," ")); cout<<endl; 
}; //main
если здесь заменить set на vector или list то все впорядке 
если на hash_set то, увы, работать не будет 
(хотя кто его знает, может быть где то и будет работать- это ведь не стандарт)

anonymous
()
Ответ на: комментарий от anonymous

2 anonymous: A зачем вообще тестировать кривые/плохие компиляторы. Кто рискнет связаться с этой гадостью, даже если она на 5-15% быстрее?
А затем, что иногда ничего, кроме них, нет.
>поэтому маленькие радости которые предоставляет valarray и прочие,
вокруг valarray нужно самому писать, к примеру, ET. ну, в общем, к valarray у меня личная нелюбовь.
>если здесь заменить set на vector или list то все впорядке если на hash_set то, увы, работать не будет
понятно, почему. для hash_set (например, из STLport) не определен
insert(iterator P,const value_type& V);
который определен для всех прочих контейнеров. По вполне понятным причинам.

AC
() автор топика
Ответ на: комментарий от AC

> Параметром шаблона может быть любой тип! > 1. и что в этом плохого?

Дык говорю же -- невозможно сразу сгенерить код оного темплата! Нужно для каждого используемого набора параметров генерить своё. А для этого либо держать весь темплат в .h-файле и включать по каждому чиху, либо таки убрать реализацию в отдельный файл .c и иметь не помню уж точно какой геморрой.

> 2. "отсечь" нежелательные типы параметров можно с помощью concept check.

1. А что есть concept check?

2. Отсечь-то -- не проблем: exceptions, RTTI, и т.п.

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

1. Бога нет!

2. Упомянуто -- может, и поболе десяти. Внятных обоснований -- не видел. Единственное, что сложно сделать макросами -- всякие конструкты на основе параметризованных типов (кой-нить typedef (PClass<Parm>* func) (int);) -- но и это, в сущности, не так уж сложно...

С уважением -- Смоляное Чучелко

anonymous
()

2AC >вокруг valarray нужно самому писать, к примеру, ET. Наверно я очень темен :-(. Подскажи глупому anonymous, что такое ET и почему без онного жизнь тебе немила.

>>если здесь заменить set на vector или list то все впорядке если на hash_set то, увы, работать не будет >понятно, почему. для hash_set (например, из STLport) не определен >insert(iterator P,const value_type& V); >который определен для всех прочих контейнеров. По вполне понятным причинам.

Ура!!! есть человек который берется объяснить почему мне приходится переписывать код, прекрасно работающий с любым нормальным контейнером (в том числе с set, который очень похож на hash_set) специально для hash_set или hash_map'a.

Итак сударь, если Вас не затруднит такая мелочь, отройте мне глаза, почему этот маленький баг в реализации нужно считать ... ээээээ... системной функцией ;-)

anonymous
()

2Смоляное Чучелко 

>1. Бога нет! 

Доказать это невозможно. В то время как обратное утверждение может быть
доказанно, но только самим Богом (если он есть :-)

>2. Упомянуто -- может, и поболе десяти. Внятных обоснований -- не видел. Единственное, что сложно сделать макросами -- всякие конструкты на основе параметризованных типов
>(кой-нить typedef (PClass<Parm>* func) (int);) -- но и это, в сущности, не так уж сложно... 
Ну и перепеши это с помощью макросов и сравни качество

#include <iostream> 

template <class T>
inline void swap(T& a, T& b)
{
  const T c = a;
  a = b;
  b = c;
}

int main (int argc, char * argv[])
{
  int aInt= 5;
  int bInt= 10;
  double aDouble= 0.5;
  double bDouble= 1.0;
  swap(aInt, bInt);
  swap(aDouble, bDouble);
  //compiler error:  no matching function for call to `swap (int &, double &)'
  //swap(aInt, bDouble); 
  cout<< aInt<<" "<<bInt<<" "<<aDouble<<" "<<bDouble<<endl;
}; //main

anonymous
()
Ответ на: комментарий от anonymous

2 anonymous: >Подскажи глупому anonymous, что такое ET и почему без онного жизнь тебе немила.
expression templates. жизнь без них немила, потому что нужно бывает без издержек гонять по векторам функции, и много векторных/матричных операций. c expression templates быстрее получается, а выглядит -- как на бумажке:)
>(в том числе с set, который очень похож на hash_set)
hash_set концептуально _принципиально_ отличается от set -- для его элементов не нужно strict weak ordering.
>Итак сударь, если Вас не затруднит такая мелочь, отройте мне глаза, почему этот маленький баг в реализации нужно считать ... ээээээ... системной функцией
потому что так устроена хэш-таблица. для ее элементов ...эээ... не определено "отношение порядка". В векторе/списке элементы хранятся в порядке вставки, в map -- в соответствии с определенным для них strict weak ordering -- а в хэш-таблице -- бог знает как, зависит от реализации таблицы. Поэтому для хэш-таблиц "итератор внутрь" не имеет смысла ни на запись, ни на "итерирование" -- только на чтение. Поэтому для хэш-таблиц и не определен insert(iterator Pos,const value_type& Value) -- не имеет смысла. С другой стороны, такой insert определен для обычных map/set, поскольку Pos можно очень эффективно использовать в качестве подсказки для начала поиска. C "третьей стороны", можно было бы определить для hash_set insert(pos,value) просто как обертку вокруг insert(value) -- но это очень спорно, и, как многим кажется, концептуально неверно. соответственно.
кроме того, если уж вам так влом переписывать код, для простых случаев можно сделать костыль в виде частичной специализации:
namespace std {
template<class t>
class insert_iterator<hash_set<t> > : //...
//bla-bla-bla
};
}

AC
() автор топика
Ответ на: комментарий от anonymous

> Ну и перепеши это с помощью макросов и сравни качество

1. Ну, уел. Отчасти. В том смысле, что как-то я не подумал о таком.

2. Ну, опишу в хидере макрос swap, генерящий inline, сразу вызову раз десять для элементарных типов, а для прочих -- буду вставлять вызов в начале файла.

Хуже -- несомненно. Принципиально хуже -- не верю! ;)

С уважением -- Смоляное Чучелко

anonymous
()

2Смоляное Чучелко

>Ну, опишу в хидере макрос swap, генерящий inline, сразу вызову раз десять для элементарных типов, а для прочих -- буду вставлять вызов в начале файла.

Ух ты, покажи как!!! Хотя бы для swap(int,int) и swap(double,double)
Как такое чудо с макросом сотворить?
мне в голову не приходит ничего кроме memcpy вместе sizeof :)

А как быть с проверкой типов?
swap(someIntValue, someDoubleValue)

В каком месте всплывет ошибка и сколько времени уйдет на поиски ляпа?

anonymous
()

2AC

>expression templates. жизнь без них немила, потому что нужно бывает без издержек гонять по векторам функции,
> и много векторных/матричных операций. c expression templates
>быстрее получается, а выглядит -- как на бумажке:) 

Что имеется ввиду????????????????
#include <iostream>
#include <valarray>
#include <algorithm>
 
double func (double argA)
{ return argA +1;}

int main (int argc, char * argv[])
{
  valarray<double> vL(1,10);
  std::transform (&vL[0], &vL[vL.size()], ostream_iterator<double>(cout," ") , func);
  cout<<endl;
  vL = sin(vL);
  std::copy (&vL[0], &vL[vL.size()], ostream_iterator<double>(cout," ")); cout<<endl;
}; //main

Все что было сказано по поводу hash_ххх контейнеров правда. Просто отсутствие кое каких мелочей в нем
вдребезги ломает саму концепцию STL: взаимозаменяемость контейнеров, a это очень важно.
Поэтому наверное они и в стандарт не попали, что безусловно плохо 

anonymous
()
Ответ на: комментарий от anonymous

>Ну, опишу в хидере макрос swap, генерящий inline, сразу вызову раз десять для элементарных типов, а для прочих -- буду вставлять вызов в начале файла. Ух ты, покажи как!!! Хотя бы для swap(int,int) и swap(double,double)

#define swapVars (Type) inline void swap (Type& a, Type& b) \ {Type& c = b; b = a; a = c;}

swapVars (int) swapVars (double)

Вот. После этого пиши swap (a, b) -- будет работать для (int&, int&) и (double&, double&). Эсли нужны ещё типы -- вставляешь swapVars (Type) либо в хидер, если часто, либо в начало самого файла, если редко.

Да, на всякий случай: в отсутствии синтаксических ошибок не уверен -- давненько я на Цэ не писал... Но отладить можно.

С уважением -- Смоляное Чучелко

anonymous
()

2Смоляное Чучелко:

действительно давненько вы на Цэ не писали... в Це нет ни ссылок ни inline

уж даже не знаю, можно это посчитать за синтаксическую ошибку и хоть как-то "отладить"...

это не считая того, что после T& c=b; b=a; c очевидно тоже поменяется :)

anonymous
()
Ответ на: комментарий от anonymous

> действительно давненько вы на Цэ не писали... в Це нет ни ссылок ни inline

Ну, описался (расставь ударения в меру своей испорченности). Разумеется, ++ в виду имелся.

Насчёт прорчего -- эсли помнишь, речь шла о макросах vs темплаты, а не о Цэ vs ++. Разумеется, пример на ++.

С уважением -- Смоляное Чучелко

anonymous
()

> 1. Читаем в column-major формате (да, мелкомягкие усиленно > 2. Пишем всё в текстовом виде > 3. *Каждый* тип поля должен форматироваться по-разному А нельзя ли переложить операцию преобразования в строку на сервер ? Тем более что тип полей заранее известен... На выходе получаем набор (например fixed-width) строк. "Клиент" работает только со строками, преобразуя их (по мере необходимости) в Unicode, обрезая пробелы и т.д...

anonymous
()

2Смоляное Чучелко:

#define swapVars (Type) inline void swap (Type& a, Type& b) \ {Type& c = b; b = a; a = c;}
>swapVars (int) swapVars (double)

Спасибо за код. Неплохо :). Дешево и сердито :)

Единственная мелочь это то,
что сообщения об ошибках будут мало понятны
да и для каждого нового типа нужно менять исходники :)
А для такой библиотеки как STL это смертный приговор


Кстати найти в исходниках функцию swap(double,double)
не так то просто
поэтому ни один нормальный генератор документации
ее не заметит и эту функцию скорее всего будет использовать
только ее автор (пока сам о ней не забудет)

anonymous
()

Тут одну страницу назад помянули MSVC. Так вот, приперло мне ДЗ собрать под Винду(препод попросил). А исходный код был писан на С++ под линухом. Прога представляла из себя реализацию целочисленного симплекс-метода. Ну и соответственно, для своих нужд был перегружен >> и << . Так вот, данный код прекрасно собирался при помощи gcc, после обработки напильником на предмет using namespace std и std::cin и так далее, был собран под MSVC++ 6.0 и _НЕ_ собрался под .NET(даже после упорной обработки напильником). Что там со стандартами МС наворотил-я не знаю. Пришлось собирать gcc под винду. А код был такой **************** #include <vector> #include <iostream.h>

template <class A> inline void Assert( char * X, A assertion, istream& is, char& tmp ) { if(assertion) { cerr << "In input stream at position: " << is.tellg() << " symbol " << tmp << endl; throw X; }; };

class cPoly { public: float coeff; double power; };

typedef vector<cPoly> cPolyContainer;

istream& operator >> (istream &is, cPolyContainer &p) { long coeff,power; int i = 0; char tmp; while ( (is.peek() != 10 && is.peek() != 13) && is) { if(p.size () <= i) { p.resize(i+1); #ifdef DEBUG cout << "p resized in operator >>" << endl; cout << "New size is:" << p.size() << " elements" << endl; #endif }; is >> coeff; if((is.peek() != 10 && is.peek() != 13)) { is >> tmp; Assert((char*) "Invalid symbol, expecting *", (tmp != '*'), is, tmp); is >> tmp; Assert((char*) "Invalid symbol, expecting x or X", ((tmp != 'x') && (tmp != 'X')), is, tmp); is >> tmp; Assert((char*) "Invalid symbol, expecting ^",(tmp != '^'), is, tmp); is >> power; p[i].coeff = coeff; p[i].power = power; i++; } else { p[i].coeff = coeff; p[i].power = 0; }; }; is.ignore(); return is; }; ostream& operator << (ostream &s, cPolyContainer& p) { int i = 0; for (int i = 0;i < p.size();i++) { s.setf( ios::showpos ); s << p[i].coeff; if (p[i].power != 0) { s << '*' << 'X' << '^'; s.unsetf( ios::showpos ); s << p[i].power; }; }; s << endl; s.flush(); return s; }; ******************* Это собссно ввод-вывод полиномов с консоли/на консоль и из файла/в файл.

angels
()

Офигенное форматирование, дубль 2
*****************
Тут одну страницу назад помянули MSVC. Так вот, приперло мне ДЗ собрать под Винду(препод попросил). А исходный код был писан на С++ под линухом. Прога представляла из себя реализацию целочисленного симплекс-метода. Ну и соответственно, для своих нужд был перегружен >> и << . Так вот, данный код прекрасно собирался при помощи gcc, после обработки напильником на предмет using namespace std и std::cin и так далее, был собран под MSVC++ 6.0 и _НЕ_ собрался под .NET(даже после упорной обработки напильником). Что там со стандартами МС наворотил-я не знаю. Пришлось собирать gcc под винду.
А код был такой 
****************
#include <vector>
#include <iostream.h>

template <class A> inline void Assert( char * X, A assertion, istream& is, char& tmp )
{
	if(assertion)
	{	
		cerr << "In input stream at position: " 
		     << is.tellg() 
		     << " symbol "
		     << tmp
		     << endl;
		throw X;
	};
};

class cPoly
{
	public:
			float coeff;
			double power;
};

typedef vector<cPoly> cPolyContainer;

		istream& operator >> (istream &is, cPolyContainer &p)
		{
			long coeff,power;
			int i = 0;
			char tmp;
			while ( (is.peek() != 10 && is.peek() != 13) && is)
			{
				if(p.size () <= i)
				{ 
					p.resize(i+1);
#ifdef DEBUG
					cout << "p resized in operator >>" << endl;
					cout << "New size is:" << p.size() << " elements" << endl;
#endif
				};	
				
				is >> coeff;
				if((is.peek() != 10 && is.peek() != 13))
				{
					is >> tmp;
					Assert((char*) "Invalid symbol, expecting *", (tmp != '*'), is, tmp);
					is >> tmp;
					Assert((char*) "Invalid symbol, expecting x or X", ((tmp != 'x') && (tmp != 'X')), is, tmp);
					is >> tmp;
				Assert((char*) "Invalid symbol, expecting ^",(tmp != '^'), is, tmp);
					is >> power;
					p[i].coeff = coeff;
					p[i].power = power;
					i++;
				}
				else
				{	p[i].coeff = coeff;
					p[i].power = 0;
				};
				
			};
			is.ignore();
			return is;
		};
		ostream& operator << (ostream &s, cPolyContainer& p)
		{
			int i = 0;
			for (int i = 0;i < p.size();i++)
			{
					s.setf( ios::showpos );
					s << p[i].coeff;
					if (p[i].power != 0)
					{
				     		  s << '*' 
				     		    << 'X' 
				     		    << '^';
						s.unsetf( ios::showpos );
						s << p[i].power;
					};
			};
			s << endl;
			s.flush();
			return s;
		};
*******************
Это собссно ввод-вывод полиномов с консоли/на консоль и из файла/в файл.

angels
()

   обнаружили  и  полюбили  некоторые  полезности  MSVC.  Моими  любимыми
   являются  Edit-and-continue и Set Next Execution Statement. В новейшем
   IDE от SUN вроде есть подобное, 5 лет спустя, между прочим...
А что такое edit-and-continue? Возможность редактировать значения пер-ных
или редактировать код "на лету"? Если первое, то gdb это может.
  Set Next Execution Statement gdb тоже может.
И gdb еще имеет встроенный язык - с ним тоже можно unicode strings смотреть,
и если извращнуться, и содержимое stl-контейнеров.

hvv
()

2YePhIcK: и что, такая оптимизация дала всего -1% загрузки CPU? Блин, и стоило так мучиться..

hvv
()

2anonymous (*) (2002-05-10 03:39:44.913)(AKA Смоляное Чучелко):

В чем-то Вы правы. Действительно, если нет никаких изменений, кроме косметических, то не стоит и городить новый Язык. Так, разрекламированный by Antichrist, Eiffel на мой взгляд не содержит в себе ничего принципиально нового по сравнению с С++. Те же шаблоны, те же классы. Только расширены права доступа (public/private/protected) и введено наследование из встроенных типов и д.р. подобные вещи.

Однако, на мой взгляд, шаблоны - новый шаг по сравнению с маркосами, поскольку макросы С обрабатывает "тупой" препроцессор, а шаблоны - "умный" компилятор. Первый ничего не знает о программе, второй - ВСЕ. С макросами в небытие уходят пространства имен. Довольно легко что-нибудь не так назвать и в это место встанет шаблон-функция или шаблон-класс, а компилятор будет нести какую-нибудь чушь. А если забыть inline будет ругаться linker. Таким образом если случайно возникнут перекрытия между двумя библиотеками их вместе использовать будет невозможно без ухищрений.

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

anonymous
()

2anonymous (*) (2002-05-10 03:39:44.913)(AKA Смоляное Чучелко):

В чем-то Вы правы. Действительно, если нет никаких изменений, кроме косметических, то не стоит и городить новый Язык. Так, разрекламированный by Antichrist, Eiffel на мой взгляд не содержит в себе ничего принципиально нового по сравнению с С++. Те же шаблоны, те же классы. Только расширены права доступа (public/private/protected) и введено наследование из встроенных типов и д.р. подобные вещи.

Однако, на мой взгляд, шаблоны - новый шаг по сравнению с маркосами, поскольку макросы С обрабатывает "тупой" препроцессор, а шаблоны - "умный" компилятор. Первый ничего не знает о программе, второй - ВСЕ. С макросами в небытие уходят пространства имен. Довольно легко что-нибудь не так назвать и в это место встанет шаблон-функция или шаблон-класс, а компилятор будет нести какую-нибудь чушь. А если забыть inline будет ругаться linker. Таким образом если случайно возникнут перекрытия между двумя библиотеками их вместе использовать будет невозможно без ухищрений.

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

anonymous
()

2anonymous (*) (2002-05-10 03:39:44.913)(AKA Смоляное Чучелко):

В чем-то Вы правы. Действительно, если нет никаких изменений, кроме косметических, то не стоит и городить новый Язык. Так, разрекламированный by A/X, Eiffel на мой взгляд не содержит в себе ничего принципиально нового по сравнению с С++. Те же шаблоны, те же классы. Только расширены права доступа (public/private/protected) и введено наследование из встроенных типов и д.р. подобные вещи.

Однако, на мой взгляд, шаблоны - новый шаг по сравнению с маркосами, поскольку макросы С обрабатывает "тупой" препроцессор, а шаблоны - "умный" компилятор. Первый ничего не знает о программе, второй - ВСЕ. С макросами в небытие уходят пространства имен. Довольно легко что-нибудь не так назвать и в это место встанет шаблон-функция или шаблон-класс, а компилятор будет нести какую-нибудь чушь. А если забыть inline будет ругаться linker. Таким образом если случайно возникнут перекрытия между двумя библиотеками их вместе использовать будет невозможно без ухищрений.

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

anonymous
()

2anonymous (*) (2002-05-10 03:39:44.913)(AKA Смоляное Чучелко):

добавление к предыдущим. На мой взгляд - разницы между макросом и шаблоном в маленькой расчетной программе (я по долгу службы в основном с такими и встречался - т.к. физик-ядерщик не доделанный, пока) практически нет. А вот как только идет что-либо типа STL+BOOST+MTL+ свое тут то и начнется конфликт имен. А вот тут уже количество спешно перерастает в качество.

Я до сих пор вожусь с Борландовской библиотекой OWL, в которой в качестве костыля для компилятора введены таблицы отклика (впрочем в MFC - тоже), а в QT слава богу для этой цели используют виртуальные функции. Так вот в их относительно несложном описании черт ногу сломит!

2All: прошу прощения за дуль.

anonymous
()
Ответ на: комментарий от anonymous

> на мой взгляд, шаблоны - новый шаг по сравнению с маркосами

Шаблоны, имхо, БЫЛИ бы новым шагом по сравнению с макросами, будь они нормально сделаны в ++.

Ей-богу, поищи в хелпах, как работать с шаблоном, который не помещается ;) в .h-файле и разбит как всякий нормальный класс/функа -- на .h и .c-файлы.

Фишка в том, что компилятор как раз НЕ ЗНАЕТ о программе "все" -- он знает только .h-файлы и текущий модель. Модуля с реализацией шаблона он как раз не знает.

Точнее говоря, дело не только в шаблонах -- дело в дурацкой (имхо) системе шаблонов вкупе с дурацкой же (это уже больше, чем имхо) модульной системой...

С уважением -- Смоляное Чучелко

anonymous
()

2anonymous (*) (2002-05-13 05:29:44.14)(AKA Смоляное Чучелко):

Не надо мне давить на больное место, то что extern не поддерживается НИКАКИМ компилятором я и так знаю. Это правда. Здесь есть недостатки и довольно крупные. Я бы назвал отсутствие extern наиболее существенным. Но мне приходилось на этой дурацкой библиотеке OWL писать окна-шаблоны (только не надо мне говорить пожалуйста, что это было глупое решение и как можно было бы сделать лучше) и честно говоря я точно знаю, что не взялся за за такую задачу, если бы мне пришлось ограничиваться макросами.

Говорят, что в Eiffel все лучше...

anonymous
()
Ответ на: комментарий от Antichrist

Antichrist, ты без сомнения самый знающий в Фортране. Может ты можешь подсказать - нужна подпрограмма минимизации функциии одной переменной с нелинейными ограничениями (как равенства, так и неравенства). Размерность задачи высокая (>1000), гессиан слабо заполнен.

anonymous
()

Появилось у меня свободное время, решил я прочитать критику Си++ Яна Джойнера,
что Луговский тут всем советовал для "прозрения". Сначала ничего так, даже многое по делу.
Дойдя до места, где он поносит указатели я подумал: "а что же он скажет
про виртуальные функции?". Пролистал до этого раздела и немного прифигел.
Там два экзампла:

class A {
public:
	void nonvirt ();
	virtual void virt ();
};

class B : public A {
public:
	void nonvirt ();
	void virt ();
};
   
A *ap, a;
B b;
ap = &b;
ap->nonvirt (); // Вызовется A::nonvirt ()
ap->virt (); // Вызовется B::virt ();

Второй отличается ненамного:

...
B *bp;
bp = &b;
bp->nonvirt ();
bp->virt ();

По утверждению Джойнера в случае bp->nonvirt() вызовется A::nonvirt(), и
это большой недостаток Си++ в виртуальных функциях.
В недоумении перечитываю.. Все тоже самое. Я в шоке.
Я вообще-то настраивался на серьезную критику Си++, а не на это.
Интересно, проверял ли Джойнер эти примеры и если да, то чем.
GCC / Intel / Watcom / Visual / Borland / Symantec - все компиляторы, что у меня есть
показали правильный результат, т.е. в случае bp->nonvirt() вызывается B::nonvirt.

Короче, читать ЭТО серьезно я уже не смогу, увы. 

anonymous
()

Чукча не читатель, чукча писатель?
Он говорит, что по ap->nonvirt() вызовется A::nonvirt(),
что неверно.
А недостаток в том, что виртуальные функции нужно объявлять явно, хотя виртуальность/невиртуальность может вычислить компилятор.
Короче, найди еще свободного времени, и прочитай еще раз.

anonymous
()

2anonymous (*) (2002-05-18 12:57:46.509): Вот это не недостаток (ap->nonvirt()), а "особенность".

И потом - я слабо себе представляю, как "виртуальность" может вычислить компилятор. Зачастую мне не нужно, чтобы функция могла быть виртуальной, даже исходя не из "скорости исполнения", а по структуре программы/библиотеки. С другой стороны - если переопределяешь функцию, которая была виртуальной, то ее переопределение так и останется виртуальной, пропускаешь или нет директиву virtual.

anonymous
()

Блин. Какие вы нехорошие, обломали провокацию.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.