![]() |
|
Модераторы: bsa |
![]()
|
|
| voral |
|
||||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 158 Регистрация: 16.3.2008 Где: Иваново Репутация: нет Всего: нет |
Не совсем правильное сравнение. Тут основное время занимает заполнение массива. Вот я почистил код. Каждый вариант запускается по три раза:
В результате у меня получися следующий вывод:
|
||||
|
|||||
| Dov |
|
|||
![]() аСинизатор ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1721 Регистрация: 10.5.2003 Где: Эрец-Исраэль Репутация: 11 Всего: 88 |
А если как-то так попробовать?
Это сообщение отредактировал(а) Dov - 1.7.2011, 00:10 -------------------- Тут вечности запах томительный, И свежие фрукты дешевые, А климат у нас – изумительный, И только соседи – #уевые. Игорь Губерман. |
|||
|
||||
| voral |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 158 Регистрация: 16.3.2008 Где: Иваново Репутация: нет Всего: нет |
Да это будет быстрее.
Это сообщение отредактировал(а) voral - 1.7.2011, 00:38 |
|||
|
||||
| newbieone |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 51 Регистрация: 14.3.2010 Репутация: 1 Всего: 1 |
Окей, практика показала увеличение производительности. А теперь теоретически это как-то можно объяснить? Я вот на прошлой странице пытался провести сравнение сложности алгоритмов "на бумажке" по количеству машинных операций, но, видимо, оно чего-то (многого) не учитывает.
Это сообщение отредактировал(а) newbieone - 1.7.2011, 09:47 |
|||
|
||||
| voral |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 158 Регистрация: 16.3.2008 Где: Иваново Репутация: нет Всего: нет |
Это о последнем алгоритме? Там все просто. Сначала бежим по каждому элементу сторки, прибавляем его у сумме и сравниваем. Как только нашли первый отрицательный элемент, нас уже не интересует есть ли еще отрицательные, по этому мы уходим в продолжение цикла где нет проверок на отрицательность, т.е. избавляемся от лишнй операции на каждую итерацию. (в предыдущем "быстром" варианте мы все равно проверяли флаг на равенство 1 или 0) |
|||
|
||||
| newbieone |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 51 Регистрация: 14.3.2010 Репутация: 1 Всего: 1 |
voral, я имел ввиду математическое пояснение в терминах теории сложности вычислений (сложности алгоритмов).
Вашего первоначального и того, что предложил borisbn. Это сообщение отредактировал(а) newbieone - 1.7.2011, 10:26 |
|||
|
||||
| voral |
|
||||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 158 Регистрация: 16.3.2008 Где: Иваново Репутация: нет Всего: нет |
а вы про этот пост где N расписывали Ну тогда както так: В худшем случае (кагда нет отрицательных числ) мы имеем N сравнений и ни одногоприсваивания В лучшем случае когда первый элемент в строке отрицателен имеем 1 сравнени и так же ни одного присваивания. Итак имеем от 1 до N (в зависимости от позиции отрицательного числа) операций против от N до 2N Добавлено через 4 минуты и 35 секунд А вообще. Если целью поставить быстродействие и если позволяет процедура заполнения матрицы. Добавить еще один одномерный массив. При вводе нового элемента матрицы анализировать существование отрицательного значения и заносить номер строки в массив. Хотя в этом случае (такой ввод) моно собственну и суму здесь же считать. Но это уже теряем гибкость. |
||||
|
|||||
| newbieone |
|
||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 51 Регистрация: 14.3.2010 Репутация: 1 Всего: 1 |
voral, не могу с вами согласиться. У вас же там в условном операторе два условия через &&, сравнений соответственно будет в два раза больше, плюс вы забываете о сравнениях (о первом из них, второе из-за short-circuiting не будет вычисляться) уже после присваивания...
Если пытаться анализировать этим способом, имеем практически одинаковые результаты: N+2 до 2N против N+1 до 2N.
Если первый элемент отрицательней, проведется 2 сравнения, 1 присваивание, и после этого еще N-1 сравнений (т.к. fexists станет равным единице, то первое сравнение даст false и дальше выражение вычисляться не будет). В сумме N+1 сравнений и 1 присваивание, т.е. N+2 операций. Если все положительные, то fexists всегда остается равным нулю и имеем 2N сравнений.
Здесь если существует единственный отрицательный элемент, N сравнений и 1 присваивание, т.е. N+1 операция. Если все отрицательные, N сравнений и N присваиваний, т.е. 2N операций. Другое дело, что способ, судя по практическим результатам, не совсем верен. Практика с теорией расходятся... Это сообщение отредактировал(а) newbieone - 1.7.2011, 13:50 |
||||
|
|||||
| voral |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 158 Регистрация: 16.3.2008 Где: Иваново Репутация: нет Всего: нет |
видимо мы о разном. Я разложил именно поселедний самый шустрый вариант. Этот же случай
я понимаю так. Самое плохое когда нет отрицательных два сравнения, сложение энд т.е. 3N - операций Самое хорошее когда первое отрицательное первая итерация два сравнения, сложение энд и присваивание 4 операции остальные итерации одно сравнение т.е. (N-1)+4 Т.е получаем от N+3 до 3N против N+1 до 2N, (кстати операция операции рознь и && совсем не одно и то же что сравнение) К тому же. У нас диапазон чисел от -1 до 9. При размере матрицы 15000 шанс что в строке не будет отрицательных чисел очень мал. Т.е. скорее всего исходный случай с одним сравнением будет стремиться именно к 2N, В то время как где два сравнения врят ли дотянет до 3N... Думаю если уменьшить размер, или увеличить диапазон чисел.... ТО может быть преимущество перейдет. Это конечно все просто рассуждения можно попробовать посмотреть на практике. Дизасемблировать оба варианта, чтоб посмотреть как это выглядит на асме; и сделать с промежуточным выводом значений... |
|||
|
||||
| newbieone |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 51 Регистрация: 14.3.2010 Репутация: 1 Всего: 1 |
Хехе, ну вот, а говорили на предыдущей странице, что
|
|||
|
||||
| voral |
|
||||||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 158 Регистрация: 16.3.2008 Где: Иваново Репутация: нет Всего: нет |
Вот еще небольшой тестик
Результат:
Добавлено через 2 минуты и 54 секунды При размере строки 11 все равно неплохой результат:
|
||||||
|
|||||||
| Kruger2 |
|
||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 94 Регистрация: 9.1.2011 Репутация: нет Всего: нет |
Через несколько глав снова вернулся к этому заданию, но уже в более продвинутом виде.
Теперь необходимо решить туже задачу, с динамическим выделением памяти. Тут я взял за основу код уважаемого voral, т.к. удобнее дописать функцию вот основа:
Вот что я добавил:
Значит функция maloc вроде бы написана без синтаксических ошибок, ибо компилятор не матерится. Однако как проверить правильно ли выделяется память я не знаю, поэтому прошу провеhить код функции maloc Далее, то что код функции freememory должен находится не тут я понимаю (ибо выделил память и тут же аннулировал), но где она должна находиться? После main? прямо перед main? Будьте добры, подскажите. |
||||
|
|||||
| voral |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 158 Регистрация: 16.3.2008 Где: Иваново Репутация: нет Всего: нет |
При выделении памяти ты заносишь адрес в переменную. Переменная имеет свою область видимости. А также, если она не глобальная, может пропасть при выходе из функции в которой существует. Ты сделал свои обертки для malloc и free. Желательно их вызывать (для одной области) в рамках однной функции - в которой живет переменная хранящая адрес. Однако, могут быть ситуации когда ты передаешь адрес в другую функцию/поток, а из той в которой создал уходишь... Тогда уже там надо позаботиться об освобождении. Например
Переменная Result будет уничтожена. Но память останется выделенной..... |
|||
|
||||
| Kruger2 |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 94 Регистрация: 9.1.2011 Репутация: нет Всего: нет |
Т.е. мне надо вызвать функцию малок внутри каждой из моих двух функций или вызвать её в мейне перед выполнением двух других функций?
Добавлено @ 14:40 и получается освобождать память тоже не надо, т.к. нет глобальных переменных ? Это сообщение отредактировал(а) Kruger2 - 11.7.2011, 14:40 |
|||
|
||||
| Kruger2 |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 94 Регистрация: 9.1.2011 Репутация: нет Всего: нет |
Вызываю внутри каждой функции сначала inmemory, затем freememory (решил переименовать малок в инмемори, что бы внести ясность) Это сообщение отредактировал(а) Kruger2 - 11.7.2011, 14:53 |
|||
|
||||
![]()
|
| Правила форума "C/C++: Для новичков" | |
|
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa. |
| 1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Для новичков | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |