Как вычислить проценты
Потребовалось вычислить проценты. Делаю по старинке
(a*100)/b
А есть ли способ сделать в Билдере с помощью функций? Или есть другой способ?
СПАСИБО!!!
мож быстрее будет ;) (и правильнее....)
быстрее будет не делить на 100 а умножить на 0.01 ;)
Нагляднее все же делить на 100, а компилятор умножит на 0.01 за тебя. :)
наглядней, то оно наглядней... только делить он дольше будет чем умножать... не думаю что компиляторы берут на себя смелость по переводу деления на умножение на обратные величины
Не поверишь, они позволяют себе и более смелые вещи. :)
b=300;
for (long int i=0; i<1000000000; i++)
a=b/100;
for (long int i=0; i<1000000000; i++)
a=b*0.01;
2-й вариант выполняется в 4 раза быстрее
Делаю вывод что BCB6 не заменяет самостоятельно деление умножением
b=300;
for (long int i=0; i<1000000000; i++)
a=b/100;
for (long int i=0; i<1000000000; i++)
a=b*0.01;
2-й вариант выполняется в 4 раза быстрее
Делаю вывод что BCB6 не заменяет самостоятельно деление умножением
хм...
это дебаг или релиз?
что говорит дизассемблер?
это дебаг или релиз?
что говорит дизассемблер?
и дебаг и релиз работают примерно однаково
дизасемблером пользоваться не умею а эезюшник сюда не прицепляется, говорят велик зараза... вот проект(если не лень заниматься):
ЗЫ: вот нашел алгоритм деления двоичных чисел, видно что он намного длинее алгоритма умножения
b=300;
for (long int i=0; i<1000000000; i++)
a=b/100;
for (long int i=0; i<1000000000; i++)
a=b*0.01;
2-й вариант выполняется в 4 раза быстрее
Делаю вывод что BCB6 не заменяет самостоятельно деление умножением
А как вы замеряли время выполнения? Использовали какие-то средства для профилирования?
проект открой, там все написано
А в вашем алгоритме каким либо образом учтена система выделения времени потокам в виндовс?
Что если какой-то процесс с более высоким приоритетов вклинился во время рассчета?
Хорошо, пусть будет ваш алгоритм замера производительности.
Не поленился и проверил.
Вот ваш немного модифицированный код.
b=300;
DWORD begin, end, time;
begin = GetTickCount();
for (long int i=0; i<1000000000; i++)
a = b / 100;
end = GetTickCount();
time = end - begin; // in milliseconds
wprintf(L"Time:%d\n", time);
begin = GetTickCount();
for (long int i=0; i<1000000000; i++)
a = b * 0.01;
end = GetTickCount();
time = end - begin; // in milliseconds
wprintf(L"Time:%d\n", time);
wscanf(L"%d", &a);
В отладочной версии как и было вами замечано время выполнения сильно отличалось в двух вариантах:
Time:4062
А вот в релизной конфигурации с включенной оптимизацией
получилось вот так:
Time:0
Отсюда можно сделать ряд выводов, например о том, что иногда нужно посмотреть нужные опции компилятора для включения оптимизации.
Кстати в данном случчае оптимизатор, проанализировав код, заметил, что после цикла, переменные ни где более не используются и просто удалил весь цикл, что видно и в дизассемблере.
Если хотите, могу скинуть дамп.
Такие дела.
Что если какой-то процесс с более высоким приоритетов вклинился во время рассчета?
я запускал оба алгоритма по нескольку раз и при этом все приложения позакрывал... так что вероятность вклинивания стороннего процесса весьма мала...
Если хотите, могу скинуть дамп.
а ежели использовать результаты вычисления, что на это скажет оптимизатор?
ЗЫ: понятное дело, если он выкинул весь код, то и сравнивать нечего...
попробуйте потом применить эти переменные где нибудь (записать хотя бы в тот же TLabel::Caption = a), а потом делать выводы
main() {
double a, b;
b=300;
for (long int i=0; i<1000000000; i++)
a=b/100;
}
mul.c:
main() {
double a, b;
b=300;
for (long int i=0; i<1000000000; i++)
a=b*0.01;
}
$ g++ div.c -o div
$ time ./div
real 0m21.291s
user 0m21.157s
sys 0m0.004s
$ g++ mul.c -o mul
$ time ./mul
real 0m3.617s
user 0m3.616s
sys 0m0.004s
теперь внимание.
$ g++ -O2 mul.c -o mul
$ time ./div
real 0m0.003s
user 0m0.004s
sys 0m0.000s
$ time ./mul
real 0m0.003s
user 0m0.000s
sys 0m0.004s
почуствуйте разницу :)
да, тестировалось на
gcc version 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)
ЗЫ: оно вобщем то и понятно почему...
ЗЫ: понятное дело, если он выкинул весь код, то и сравнивать нечего...
попробуйте потом применить эти переменные где нибудь (записать хотя бы в тот же TLabel::Caption = a), а потом делать выводы
Т.е. вы хотите сказать, что компилятор не может оптимизировать умножение и деление, хотя запросто может анализировать логику кода, удалять неиспользуемые блоки и т.д.?
Ладно, будем проверять дальше.
Вот код:
b=300;
DWORD begin, end, time;
begin = GetTickCount();
for (long int i=0; i<1000000000; i++)
{
a = b / 100;
b = a;
}
end = GetTickCount();
time = end - begin; // in milliseconds
wprintf(L"Time:%f - %d\n", a, time);
begin = GetTickCount();
for (long int i=0; i<1000000000; i++)
{
a = b * 0.01;
b = a;
}
end = GetTickCount();
time = end - begin; // in milliseconds
wprintf(L"Time:%f - %d\n", a, time);
wscanf(L"%d", &a);
Результат:
Time:0.000000 - 19969
Разница есть, но не такая большая :cool:
Все таки оптимизация есть... :)
я говорил о том что он не возьмет на себя смелость заменить деление умножением.
а логика кода - если не используется нигде вычесленное значение, то удалить вычисление - здесь как раз логика проста
на
И.. о чудо :)
Результаты почти сравнялись, что можно отнести на сторонние потоки.
Time:0.000000 - 28750
Делайте выводы и как сказал squirL, чувствуйте разницу :)
на
И.. о чудо :)
Результаты почти сравнялись, что можно отнести на сторонние потоки.
Time:0.000000 - 28750
Делайте выводы и как сказал squirL, чувствуйте разницу :)
я даже могу предположить как происходила оптимизация деления: т.к. 1 (единица) и 100 являются константными, а деление и умножение равные по приоритету задачи, оптимизатор заранее высчитал 1/100 и подставил 0,01, что равно формуле умножения, а разница во времени появилась из за того что все таки пришлось вычислять 0,01
Оптимизация происходит на этапе компиляции а не во время выполнения.
ну вот на этапе компиляции он 1/100 превратил в переменную "с" а чуть выше цикла сделал примерно так c=1/100... ну это так, чисто теоретические догадки и предположения...