- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
unit HRTimer;
interface
uses Windows;
type
// --------------------- Класс - высокоточный таймер -------------------------
THRTimer = class(TObject)
constructor Create;
function StartTimer: Boolean; // Обнуление таймера
function ReadTimer: Double; // Чтение значения таймера в миллисекундах
private
StartTime: Double;
ClockRate: Double;
public
Exists: Boolean; // Флаг успешного создания таймера
end;
var
Timer: THRTimer; // Глобальая переменная. Создаётся при запуске программы
{ Фукнция высокоточной задержки.
Delphi:
Синтаксис: function HRDelay(const Milliseconds: Double): Double;
Milliseconds: Double - задержка в миллисекундах (может быть дробной)
Результат функции - фактически произошедшая задержка с погрешностью.
Пример вызова функции: X:= HRDelay(100.0); или HRDelay(100.0);
C++Builder:
Синтаксис: double HRDelay(const double Milliseconds);
Double Milliseconds - задержка в миллисекундах (может быть дробной)
Результат функции - фактически произошедшая задержка с погрешностью.
Пример вызова функции: double X = HRDelay(100.0); или HRDelay(100.0);}
function HRDelay(const Milliseconds: Double): Double;
implementation
function HRDelay(const Milliseconds: Double): Double;
begin
Timer.StartTimer();
repeat
Result:= Timer.ReadTimer();
until Result >= Milliseconds;
end;
{ THRTimer }
constructor THRTimer.Create;
var
QW: LARGE_INTEGER;
begin
inherited Create;
Exists := QueryPerformanceFrequency(Int64(QW));
ClockRate := QW.QuadPart;
end;
function THRTimer.StartTimer: Boolean;
var
QW: LARGE_INTEGER;
begin
Result := QueryPerformanceCounter(Int64(QW));
StartTime := QW.QuadPart;
end;
function THRTimer.ReadTimer: Double;
var
ET: LARGE_INTEGER;
begin
QueryPerformanceCounter(Int64(ET));
Result := 1000.0 * (ET.QuadPart - StartTime) / ClockRate;
end;
initialization
Timer:= THRTimer.Create();
finalization
Timer.Free();
end.
---
Ну и зачем LARGE_INTEGER непонятно, все же напрямую приводится.
оно так красиво оформлено, что я тоже не сразу заметил :)
ClockRate: Double;
надо было int64
2. весь класс поместить в implementaion
3. самое важное - hrdelay нагружает процессор. нужно sleep добавить при долгих (к примеру >0.1 сек) паузах.
2. Нет, может пользователь для своих целей будет юзать, не только для delay
3. Ну, может он сделан для небольших пауз. Тогда будет излишнее усложнение.
3. усложнение, но небольшое. для небольших пауз так и надо.
кстати, вопрос чем sleep не понравился?
дык, ради этого и постилось
еще есть 4. странная хуита видимостью мемберов
> может он сделан для небольших пауз
multimedia timers, не? чтоб процом-то не тормозить...
В винде (во всяком случае winXP) квант выделяемого задаче времени - 15мс. Так что задержку в 10мс не сделаешь никак, кроме такой вот жадной реализации.
Да вот возмёт винда и вытеснит твой жадный слип на другую задачу... Так что это тоже не гарантия 10 мс
Ага, и приложение зависая - убивает всю ось до следующей перезагрузки ресетом... Конечные пользователи, вам это не простят.
Так вот, я за АВТОдеструкторы. А ручные деструкторы - это полный пиздец, кто только эту хероту придумал.
заюзай интерфейсы и будут тебе объекты уничтожаться в Release.
ЛОЛШТО?
почитай википедию, чтоли
действительно костыльно...
Кому как, меня например не напрягает.
Код с ручными деструкторами:
Тебя это не напрягает? Или ты не заботишься об исключениях, о том, что надо в каждой точке выхода прописать все вызовы деструкторов?
Не-не-не, нахуй такое ООП.
Я использую ООП для более-менее стабильных сущностей - всяких там групп приводов, существ, предметов и т.д. Для них я точно знаю, когда они должны создаваться и когда исчезать.
Да, слегка неудобно что я не могу прозрачно обернуть в объект скажем строку или set, но не отказываться же из-за этого от паскаля.
Ага, на одной платформе один диалект, на другой - другой.
Ада куда более кросплатформенна.
Хотя я с винды слазить не собираюсь, мне пофиг.
> А что автодеструкторов нет - ну да, чуток лишнего кода приходится написать, но это же не главное.
А сидеть на пороховой бочке тебя тоже не напрягает? Что программа может взять и потечь из-за того, что где-то какой-то случай не разобрал?
Один диалект (FreePascal) на все платформы. Ну и Дельфи на винде, слегка отличающимийся по фичам, зато с более эффективным компилятором.
>А сидеть на пороховой бочке тебя тоже не напрягает? Что программа может взять и потечь из-за того, что где-то какой-то случай не разобрал?
К моему стыду нет. Мой софт на спутники не ставят, а если возникает непредвиденное исключение (причем не один раз возникает, а начинает все время возникать, иначе меморилика серьезного не будет), то обычно виноват какой-нибудь баг в программе и утечка памяти становится наименее важной из бед.
Когда будут ставить, когда будешь трястись по ночам за каждый баг, то поймёшь, какая жопа - ручные деструкторы.
Ну и что? А оператор присвоения на что? Ну передашь ты ссылку, у тебя объект сразу же скопируется (либо счётчик ссылок увеличится), какие проблемы?
А GC лажа. Он не поможет вовремя закрыть файл или освобдить критическую секцию.
и в результате не убьется. А его контейнер, к которому он относился уже убился, например. Так что когда этот обьект начнет удалятся, будет эксепшн. Хотя если правильно писать... может и не будет.
Вот для критических секций и файлов имхо и так все ясно. Один раз создали, один раз удалили. Если в локальной процедуре юзаем - обернули в try.
Так, иди изучай auto_ptr и shared_ptr, потом продолжи разговор. Это азы, объяснять их я не вижу смысла. Да и лень врубаться в то, что ты имеешь в виду.
> Вот для критических секций и файлов имхо и так все ясно. Один раз создали, один раз удалили.
А где именно удалили? А если из процедуры много выходов? Зачем руками следить за тем, для чего есть средства языка?
Я к тому, что всех проблем с памятью это само по себе не решит, все равно думать об области видимости надо.
>А где именно удалили? А если из процедуры много выходов? Зачем руками следить за тем, для чего есть средства языка?
В Аде - незачем, раз есть средства языка.
В Паскале - вполне нормально следить.
CS := TCriticalSection.Create;
try
... работаем с ней, можем вызывать exit сколько хотим
finally
CS.Free;
end;
Автодеструкторы сэкономили бы три строчки.
В серьёзных проектах это явно не так...
Если он пишет на дельфи, то наф? Лучше уж пусть другие языки посмотрит.
Это ручная работа, а ты человек, а значит обязательно ошибешься. Мало того, что в софте будут ошибки, так ещё потом придется их отлаживать и тратить на это время. Лучше бы ты это доверил компилятору.
Это тупая работа, если это может сделать твой компилятор. Лучше ты за это время напишешь пару лишних программ, а значит больше заработаешь и уедешь на Карибы или просто будешь пинать балду, написав "недельную" программу за день, тк большую часть работы сделал за тебя компилятор..
А причём тут шаблоны, когда мы паттерн автодеструкторов обсуждаем и перекладывания работы на компилятор?
>5%
Хрена себе... 5% Да с моими то проектами - я бы убился это писать и особенно отлаживать.
Опасность не убитых объектов не только в утечках памяти, а в утечки прочих важных и не очень ресурсов и нарушениях логики работы программы.
Например, в многопоточном программировании используется паттерн:
При создании объекта - лочится семафор, а при удалении объекта - его отпускает. Это крайне удобно, тк не важно какое исключение бы не произошло - логика программы не нарушится, тк семафор все равно будет разблокирован при удалении объекта.
Вот, если бы часть работы компилятор языка делал за тебя, то баг бы такой может быть бы и не возник. Например он бы вызвал за тебя деструктор при исключениях или просто за тебя, даже когда ты бы забыл. В конце концов, проверил бы тип объекта или не меняешь ли ты константный объект.
Кстати, в дельфи это типичная ситуация, когда приходится использовать "безтиповый" pointer или variant или ещё какой хак, что-бы написать универсальную коллекцию. В то время, когда в языке есть шаблоны - коллекция может проверить во время компиляции тип элементов, которые в неё кладут.
Это не шаблоны, это генерики. Они есть.
Очень смешно.
>Дельфи - всю работу менеджер памяти на себя берет.
Знаем, как он на себя работу берёт. Дельфи-программы всегда славились хорошей утечкой памяти...
А вот для остального почему-то ботланд не додумался сделать автодеструкторы. Зато он додумался в языке без ГЦ и автодеструкторов сделать классы, экземпляры которых создаются В КУЧЕ. Я считаю, что это рак мозга.
Может складывать объекты в dynмассивы, что-бы у них деструктор сам вызывался? :D
Но класть числа в динмассив длины 1 мне один раз пришлось.
Вообще это из моего калькулятора (архив с исходниками): http://tarasber.narod.ru/MiniCalc.rar
Функция взятия следующей лексемы из строки:
>narod.ru
your post gave me a feel
>Topacer
Торасег? Торасег? Да вам явно нужен ник антитарасег.
Я не Торасег. Я Топацер!
альзо:
> Ошибка выскакивала
а коде говнище начинается уже с тупо скопипащенной венгерки
можно постить, воняет как треска
ты - идиот, читай справочник, там черным по английскому написано почему погрешность и как с ней бороться.