![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Быстрый Swap,
main © (2008-11-15 20:02:00)Нужна максимально быстрая процедура, которая меняет местами содержимое блоков памяти. Что-то вроде:
procedure QuickSwap( Source,Dest :pointer; count :integer );
begin
???
end;
Почему такой процедуры нет среди стандартных? О_о
main (2008-11-16 00:03:00) [61]Интересно почему переместили в "начинающим"?
Разве это так уж элементарно?
...
> Кроме того при таком размере беспокоиться о скорости, это
> экономия на спичках.
А если нужно очень много раз применить,
например такая стандартная задача:
Есть ОЧЕНЬ большой массив record'ов.
Вот нужно дапустим его определенным образом отсортировать.
И размер одного record"а допустим НЕ маленький.
И все это в динамической игре и в реальном времени, да чтоб не тормозило и было как минимум 30 кадров в секунду, и это только малая часть всех расчетов ...
И вобщем-то 3 вызова move не желательно, т.е. надо бы без move.
Там где это можно я тусую указатели.
Но иногда возникает необходимость тусовать именно данные.
...
Ну нет, так нет, значит самому придется писать. :(
palva (2008-11-15 23:28:00) [62]При обмене не надо писать в промежуточную память. Нужно вести обмен в цикле по четыре байта, используя регистры. Ну то есть память по первому пойнтеру пишем в EAX, по второму пойнтеру - в EDX, потом возвращаем данные в память, но поменяв местами. Затем увеличиваем пойнтеры на 4. Последнюю порцию, которая может не равняться четырем, обмениваем побайтно. Естественно, что писать на ассемблере. Может быть, можно добиться хорошего кода и на делфи, но этого не так легко добиться - больше времени убьете.
Вполне возможно, что тройной move будет работать быстрее, поскольку он эффективно реализован. Но тогда будут хлопоты с выделением и освобождением памяти. Непонятно, что в конечном счете окажется лучше. Надо пробовать.
Johnmen (2008-11-15 23:21:00) [63]
> main © (15.11.08 20:02)
Это эквивалентно поменянию значениями указателей
:)))
Anatoly Podgoretsky (2008-11-15 23:04:00) [64]> main (15.11.2008 22:37:06) [6]
Зачем на стеке, стек маленький, зато куча большая.
Менять можно небольшими порциями, но скороть будет значительно меньше.
Это тебе домашнее задание протестировать это.
Для случая 1024 без разницы где объявлять, это не размер.
Кроме того при таком размере беспокоиться о скорости, это экономия на спичках.
main (2008-11-15 22:43:00) [65]Подчеркну, мне нужна не какая-нибудь, а именно быстрая, желательно самая быстрая. :)
А просто какую-нибудь я и сам сейчас за минуту напишу, и даже много разных.
main (2008-11-15 22:37:00) [66]
> Anatoly Podgoretsky © (15.11.08 21:58) [5]
> > main (15.11.2008 20:27:02) [2]Обмен сводится к трем
> move.Видимо данная функция мало кому нужна, поэтому и не
> включили.Правда иногда Борланд шел навстречу подобным заявкам,
> например когда делал IncDay
А если размер данных большой, и их размер заранее не известен,
надо ведь еще под временный буфер память выделить.
Это как-нибудь можно на стеке динамически выделять?
А может небольшими порциями менять быстрее?
П.С.
Я вобщем-то для своего частного случая объявил в начале процедуры:
var temp :array[0..1023] of byte;
Т.к. у меня известно что count <= 1024
Но хотелось бы универсальное решение ... :)
Anatoly Podgoretsky (2008-11-15 21:58:00) [67]> main (15.11.2008 20:27:02) [2]
Обмен сводится к трем move.
Видимо данная функция мало кому нужна, поэтому и не включили.
Правда иногда Борланд шел навстречу подобным заявкам, например когда делал IncDay
tesseract (2008-11-15 21:18:00) [68]
> move - копирует, а мне нужно именно менять местами.
2 move. Случай сильно прикручен.
main (2008-11-15 20:32:00) [69]Погуглил, ничего стоящего не нашел.
В принципе я и сам могу что-нибудь намутить, только вот стоит ли изобретать велосипед,
это ведь стандартная рутина, наверняка уже есть готовые решения.
С удовольствием бы скопипастил! :)
Интересно, почему такой процедуры нет среди стандартных? О_о
main (2008-11-15 20:27:00) [70]
> tesseract © (15.11.08 20:17) [1]
> move. Стандартнее не бывает. Читайте документацию.
move - копирует, а мне нужно именно менять местами.
Я немного не правильно написал:
procedure QuickSwap( PData1,PData2 :pointer; count :integer );
begin
???
end;
tesseract (2008-11-15 20:17:00) [71]move. Стандартнее не бывает. Читайте документацию.