Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2002.10.14;
Скачать: [xml.tar.bz2];

Вниз

Array   Найти похожие ветки 

 
Kolya   (2002-10-02 02:28) [0]

Здравствуйте Мастера!
Моя программа работает с array of long. В 90% случаев требуются всего лишь 50-100 переменных, но иногда может потребоватся и несколько тысячь. Мне не хочется создавать array с 5000 переменных, поскольку это будет занимать очень много памяти (5000 x 4b = 20k). Гораздо лучше было бы сделать array с 50 переменными и только в 10% случаев разширять его до 5000. Возможно ли это? Заранее спасибо!


 
Gayrus   (2002-10-02 03:40) [1]

Да запросто :)
arL:array of long;
...
SetLength(arL,5000);

Юзай на здоровье.


 
Kacnep   (2002-10-02 07:29) [2]

Верно ! Посмотри Динамические массивы хотя где то читал что на самом деле они несовсем динамические но это уже дебрии


 
Кот Бегемот   (2002-10-02 08:59) [3]

Блиннн, Kolya ты извращенец
Купи памяти :-\

У мя массывы занимают по несколько метров -
Например 84000*64 - и я не парюсь

20к - даже для вируса мало


 
Polevi   (2002-10-02 09:02) [4]

>Кот Бегемот © (02.10.02 08:59)
молодец, чем больше памяти жрет программа, тем она круче !!


 
VAleksey   (2002-10-02 09:06) [5]

не забудь освободить динамический массив после работы
arL:=nil



 
raiv   (2002-10-02 09:20) [6]

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

....
SetLength(arL,I);
Чтение I числа
Inc(I);
...


 
MBo   (2002-10-02 09:37) [7]

>raiv
Нехороший совет ;(
Постоянная реаллокация дин. массива ни к чему.
Эмпирическое правило: сразу задать такой размер, которого хватит в 80% случаев, при заполнении массива увеличивать длину на 20-25%


 
raiv   (2002-10-02 09:44) [8]

Я этим постоянно пользуюсь и никаких проблем (D6). Раньше я это делал на C++. А в книгах по Delphi даже советуют это делать правда для D6. К тому же ты берешь ровно столько памяти - сколько нужно.


 
MBo   (2002-10-02 09:48) [9]

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


 
Mike Kouzmine   (2002-10-02 10:05) [10]

MBo © (02.10.02 09:48) а как ты определишь сколько массив имеет реальных значений. Что значит замедляет работу? На С1000 что так, что эдак - лишние доли секунды еще ни кому не мешали, зато я могу определить for i := 0 to High(Arr) do не парясь и не заботясь о определении - какая реальная длинна массива. И добавлять проще - SetLength(Arr,High(Arr) + 1);


 
Polevi   (2002-10-02 10:09) [11]

а потом все удивляються - мой суперпупер п4 тормозит !!


 
Кот Бегемот   (2002-10-02 10:14) [12]

Винда достаточно умная (???) все равно, выделяете вы память по биту или по метру, засунет ее в файл подкачки :(


 
Mike Kouzmine   (2002-10-02 10:17) [13]

Странное замечание Polevi © (02.10.02 10:09). Мои программы и на 166 работают не проваливаясь (ну кроме длительных запросов к базе), и время прошло, когда надо было считать байты.


 
MBo   (2002-10-02 10:23) [14]

>Mike Kouzmine
В разных ситуациях и действовать нужно по-разному.
Если имеется крупный массив увесистых записей, просто нелепо при каждом добавлении одной записи делать реаллокацию.
Вот и TList подобным образом работает - по достижении предела добавляется место сразу под несколько указателей.


 
Polevi   (2002-10-02 10:40) [15]

2Mike Kouzmine (02.10.02 10:17)
сначало байты не считаем, потом мегабайты в файл подкачки, а может просто алгоритм надо передумать по другому ?
иногда несколько строчек кода может в десятки раз снизить треббования к памяти и процессору, но щас это типа не модно головой думать, пусть ОС за нас думает и юзеры за мегабайтами в магазин бегут


 
Mike Kouzmine   (2002-10-02 10:52) [16]

У американцев есть хорошая привычка считать деньги, зачем тратить больше денег на охрану гос секрета, если его опубликование принесет меньший урон, так и здесь - моему работадателю выгодней получить проект пораньше, доплатив 20 долларов за железо, чем я буду вылизывать алгоритм неделю. Хотя такой ситуации я не припомню. А ваш подход устарел еще при переходе на 386 процессоры. А размышления о байтах, мегабайтах и прочем железе - притянут за нос.


 
Игорь Шевченко   (2002-10-02 11:00) [17]

Mike Kouzmine (02.10.02 10:52)

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


 
Polevi   (2002-10-02 11:06) [18]

2Mike Kouzmine (02.10.02 10:52)
часто речь идет не о неделях а минутах, но вам лень мозги напрягать, у вас работодатель богатый
и что это за МОЙ подход такой интересно ??
то есть по вашему есть американский подход а есть какойто другой, которому я следую, так что ли ?
вы когда работу будете искать другую, в резюме свой подход опишите, будет куча предложений


 
KSergey   (2002-10-02 12:08) [19]


> Mike Kouzmine (02.10.02 10:17)
> Странное замечание Polevi © (02.10.02 10:09).


А чем оно странное?! Абсолютно правильно!

[Все что написано далее не совсем буквально так работает в вндовс, там защищенный режим, но в принципе довольно близко]

Тут ведь вот в чем дело: выделили, например, памяти 1 байт. Теперь говорим: "не, надо 2". Операционка говорит "Ок", буфер в 1 байт бросает, помечая его как свободный, выделяет в другм месте буфер в 2 байта (копируя туда данные). А мы ей тут опять: "А не, теперь 3 надо". Операционка опять бросает буфер в 2 байта и выделяет новый - длиною в 3 (копируя туда данные). Ну и т.д.
Во-первых, вы заметили, сколько копирований и прочих накладных расходов произошло?!
Во-вторых, буфера в 1 и 2 байта лежат пустыми, дефрагментируя память, при этом они вроде как пустые, но при следующей операции выделения памяти например в 500 байт ее может и не хватить, т.к. нет сплошного подходящего куска, а есть много мелких... Да. операцонка их еще иногда склеивать начинает - тоже процесс не из быстрых.
Почему операционка постоянно выделяет новый буфер а не удлинняет имеющийся? Так вообще-то не одна наша программа крутится, это раз. А два - и наша программа не один раз выделяет всякие кусочки в памяти - имеющемуся буферу, возможно, просто некуда расти - за ним уже лежит блок, выделенный в другом месте приложения (только не говорите, что вы выдляете память в одном месте и все. А как себя ведет и что делает VCL вы в курсе? (не в смысле, что ведет она себя плохо, а просто она тоже постояно выделяет/освобождает память)
Не спешите в меня плевать, я понмаю, что все оно не совсем так, что операционка выделяет не по 1 байту, а кусками, крантыми какой-то величине (Win по 4кБ, если не ошибаюсь) и в пределах этого куска размер буфера просто наращивается, но это актуально при выделении по 1 байту на раз. А что, если каждый раз увеличение больше, чем квант (один или несколько) выделения памяти? Тогда "предусмотрительность" (хотя и не в ней дело, но пусть будем думать, что это так) операционки нас ну никак не спасает. Память все равно дефрагментируется.

Так что алгоритм, предложенный MBo © (02.10.02 09:37) как раз очень правильный и разумный.


> Mike Kouzmine (02.10.02 10:05)
> MBo © (02.10.02 09:48) а как ты определишь сколько массив
> имеет реальных значений.


Не знаю как делает MBo, а я - элментарно: завожу переменную, в которой это все отслеживаю. (переменная жрет память? Так вроде байты мы перестали считать?)

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


 
KSergey   (2002-10-02 12:18) [20]


> Mike Kouzmine

Как некоторое дополнение: тут речь не о байтах и мегабайтах: если для решения задачи необходимы террабайты памяти и заказчик готов за это платить (возможно, что другого пути просто нет), то сколько угодно! Но в данном вопросе вы элементарно ошибаетесь, и вам просто указывают на ваши ошибки, при этом, заметьте(!) не принужная следовать укозявкам.

Или вы посещаете форум для каких-то других целей? ;)


 
Mike Kouzmine   (2002-10-02 13:12) [21]

Речь не о том, а то что считать байты пора заканчивать, именно, я не знаю, что вы пишите, может систему оповещения о ядерной атаке, которая должна отслеживать миллион объектов в реальном времени, я занимаюсь базами данных, где для манипулирования большими объемами данных используются другие механизмы. Я хотел сказать, что для больших объемов данных надо использовать базы данных, а если вы используете массивы, то флаг в руки.
Теперь отвечу -
"Не знаю как делает MBo, а я - элментарно: завожу переменную, в которой это все отслеживаю. (переменная жрет память? Так вроде байты мы перестали считать?)" - а если ошибка и не увеличился счетчик (любое исключение), да не одно? Универсальность и надежность подразумевает накладные расходы и надо это принимать или не принимать. Что вы и делаете (не принимаете).


 
Alex4444444444   (2002-10-02 14:11) [22]

To KSergey (iz Delphi help):

memory manager zaprashivaet u OS pamyat" kuskami po 1M i commit ee (uzh ne znayu, kak eto skazat" po russki) kuskami po 4K. (Na skol"ko ya znayu, nel"zya v principe poluchit" stranitsu ne kratnuyu 4K, no eto uzhe detali.)


 
KSergey   (2002-10-02 14:26) [23]

Alex4444444444 (02.10.02 14:11)

Я правда не совсем понял, что вас возмущает... Вроде так у меня и написано после "основной" части. А то, что дельфи хватает куски по мегабайту - ну так в борланде же прекрасно понимают, что часто будут выделяться именно небольшие куски (под динамически создаваемые объекты, например) - вот они и пытаются описанную мною (не путать с мною придуманную!) методику сами использовать для уменьшения всяких проблем.


> Mike Kouzmine (02.10.02 13:12)
> "Не знаю как делает MBo, а я - элментарно: завожу переменную,
> в которой это все отслеживаю. (переменная жрет память? Так
> вроде байты мы перестали считать?)" - а если ошибка и не
> увеличился счетчик (любое исключение), да не одно? Универсальность
> и надежность подразумевает накладные расходы и надо это
> принимать или не принимать. Что вы и делаете (не принимаете).


Про надежность: а как вы думаете, как реализована ф-ция Length (ну или Hight)? А ведь в ней как раз и читается переменная, куда все записывается, только записывается силами VCL. Так что исключениям и она подвержена, значит и там точно такие же проблемы потенциально есть. А обработку исключений и я могу написать.
Хотя я конечно не буду спорить - где-то это вполне проходит, и я так делаю: надо в ф-ции массивчик небольшенький - да и фиг с ним, понаращиваю поэлементно, не страшно, все равно при выходе из ф-ции очищу. А вот когда приходится делать глобальный динамический массив в программе - вот тут я репу все же чешу и напрягаюсь. Может я и не прав...


 
Th   (2002-10-02 14:40) [24]

Ребята, чем спорить, лучше ответьте мне на маленький вопрос ;))
Что корректнее:

SetLength(Matrix,0,0);

или

Matrix:=nil;

???


 
Mike Kouzmine   (2002-10-02 15:00) [25]

SetLength(Matrix,0);
Если исключение происходит при увеличении массива, то он и не увеличится, что не скажешь про отдельный счетчик


 
Th   (2002-10-02 15:02) [26]

THank"s


 
Vitalik   (2002-10-02 15:41) [27]

> KSergey
А если у меня массив описан, например, так:

a: array of array of integer;

Setlength(a, 10);
... то когда я делаю следующее...
SetLength(a[5], 10);
...то в памяти копируется весь массив a, или только a[5]?
Учитывая Вашу поправку ("Не спешите в меня плевать...") от (02.10.02 12:08), перефразирую вопрос:
В памяти массив a вместе со своими элементами-массивами (a[0]...a[n]) рассматривается как единое целое? Или сам массив а является массивом указателей, и значит изменение размеров его элементов не влияет на него самого?

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


 
Yegor Derevenets   (2002-10-02 16:21) [28]

Люди! А не проще ли написать какой-нибудь прямой объект или класс, выполняющий операции с массивом ов Long? Будет что-то вроде:

type
TLongArray=array of Long;
PLongArray=^TLongArray;
TArrayObject=object (TObject)
Data: PLongArray;
Count: Long;
constructor Create (aCount: Long);
procedure SetRange (aNewCount: Long);
procedure SetValue (aIndex, aValue: Long);
function GetValue (aIndex): Long;
destructor Destroy;
end;

В Create инициализировать Data, в SetRange выделять новый кусок из кучи, пихать в него все, что помещается, из старого и обновлять Data и Count. В SetValue если aIndex>=Count, то SetRange (aIndex+128); В GetValue тоже делать что-то наподобие.
Если кому надо - могу написать до конца. Вопщем, пишите на мыло!

P.S. Идея не нова - примерно так написаны коллекции в Object Pascal (потому и вмещали только 16380 элементов).


 
REA   (2002-10-02 16:40) [29]

На больших объемах лучше сначала узнать размер и потом не перераспределять часто - работает медленно. На малых можно и по 1 прибавлять.


 
Mike Kouzmine   (2002-10-02 17:46) [30]

Это называется база данных. Ее не надо придумывать, а надо использовать или сервер или нативные форматы. Тем более в этом случае решены проблемы сортировки, поиска и прочие приблуды.


 
KSergey   (2002-10-03 06:43) [31]


> Vitalik © (02.10.02 15:41)
> > KSergey
> А если у меня массив описан, например, так:
>
> a: array of array of integer;
>
> Setlength(a, 10);
> ... то когда я делаю следующее...
> SetLength(a[5], 10);
> ...то в памяти копируется весь массив a, или только a[5]?

Опа.... Хороший вопрос.. Я действительно не знаю как хранится массив в дельфи. В Си - знаю, а тут - нет.. В тех 2 книжках по D что у меня есть, этот вопрос не освещен (хотя странно; в любой книжке по Си эта тема обязательно разжевывается). А шибко лазить по хелпам - лень. Уж не взыщите.К стати, тема интересна, если чего нароете - будет интересно узнать.

> Mike Kouzmine (02.10.02 15:00)
> SetLength(Matrix,0);
> Если исключение происходит при увеличении массива, то он
> и не увеличится, что не скажешь про отдельный счетчик

Это интересно почему?! Деже если тупо написать
SetLength(a,100); // предположим, что тут произошло исключение
nASize := 100; // тогда эта строка ну никак не выполнится

Ну а уж в промышленном приложении при необходимости я точно обработаю исключения. Так что я не понимаю на чем основывается ваше утверждение.

> Th © (02.10.02 14:40)
> Что корректнее:
> SetLength(Matrix,0,0);
[1]
> или
> Matrix:=nil;
[2]

Не совсем понятно, чего вы хотите добиться: сказать, что массив теперь нулевой длины (случай 1) или освободить из под него память (случай 2)? Это вообще-то не одно и тоже. (Если кто-то несогласен - растолкую.) Так что решайте что вам надо в конкретном случае и действуйте сообразно обстоятельсвам.
И мне совершенно непонятна категоричность и однозначность, выраженная в ответе Mike Kouzmine (02.10.02 15:00)...


 
Kolya   (2002-10-03 07:07) [32]

Спасибо за советы! После каждой записи реаллокацию а делать не стал, а добавляю в массив 100 разделов вперед- Вроде все прекрасно работает.
А экономить память- это я привык с давних лет- обожаю пользовать байты вместо integer"ов, когда переменная не больше 256 :), что уж говорить про массивы


 
murza   (2002-10-03 09:32) [33]

ДА.....БЛИН.
Собрались программисты, то же мне.
А хеширование, разреженные массивы - это как, немодные слова?


 
KSergey   (2002-10-03 09:33) [34]


> murza © (03.10.02 09:32)
> ДА.....БЛИН.
> Собрались программисты, то же мне.
> А хеширование, разреженные массивы - это как, немодные слова?

Так.. Еще раз для меня тупого... и Поподробнее...


 
Anatoly Podgoretsky   (2002-10-03 09:38) [35]

Vitalik © (02.10.02 15:41)

Для такого массиве a: array of array of integer), первое измерение является массивом указателей на массивы, поэтому можно написать

SetLength(a[5], 10);
SetLength(a[6], 20);
SetLength(a[7], 3);

Этоже не двухмерный массив, а массив массивов


 
Anatoly Podgoretsky   (2002-10-03 09:46) [36]

Kolya © (03.10.02 07:07)
Ты ничего не написал про применение, про время жизни массива, в зависимости от этого могут быть различные решения, но в если исходить из представленной информации, то у тебя два пути, или выделить сразу максимальное место, это при условии если известен максимально возможный размер массива, или выделять достаточно большими кусками, как ты и поступил, здесь опять два пути или наращивать фиксированнми кусками или интеллектуально, как TList, при изменении блока, размер увеличивается пропорционально размеру массива, но кратными какой то степени 2


 
VAleksey   (2002-10-03 11:24) [37]

Добавлю потом дочитаю :)
2 Игорь Шевченко © (02.10.02 11:00)
А кто ему за это заплатит ?


 
VAleksey   (2002-10-03 11:30) [38]

А чего вы спорите - то ?
По сути - то кажись все одинаково делают.


 
Игорь Шевченко   (2002-10-03 11:39) [39]

VAleksey © (03.10.02 11:24)

Эта...вопрос не так поставлен :-)
Я бы за его подход просто уволил бы :-)))


 
Le Taon   (2002-10-03 12:31) [40]

Mike Kouzmine
Твой подход может годиться только для
пользовательского кода самого верхнего уровня разового применения, набитого на живую нитку в режиме цейтнота.
(один мой знакомый называет его "живопырка").

Код ядра никогда так никогда не писался и писаться не будет,
вне зависимости от частоты процессора и объёмов памяти.



Страницы: 1 2 вся ветка

Форум: "Основная";
Текущий архив: 2002.10.14;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.57 MB
Время: 0.008 c
1-45455
soware
2002-10-03 08:13
2002.10.14
Колесо МЫШИ


1-45441
Демонов Е.В.
2002-10-03 12:08
2002.10.14
Вопрос О Процессах


14-45500
asderg
2002-09-14 19:20
2002.10.14
Господа, (возможно коллеги) :)) неужели...


4-45638
anato
2002-08-31 00:34
2002.10.14
Как запретить показ меню Пуск?


1-45366
Lony
2002-10-06 11:38
2002.10.14
Visible формы.





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский