Нашли или выдавили из себя код, который нельзя назвать нормальным,
на который без улыбки не взглянешь?
Не торопитесь его удалять или рефакторить, — запостите его на
говнокод.ру, посмеёмся вместе!
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.
классический шайзберг посреди майских роз (ну почти розы)
var Timer: THRTimer; можно перенести после implementation, чтоб шаловливыми ручонками не трогали. А так - не вижу в чем беда, у меня похожий класс есть.
---
Ну и зачем LARGE_INTEGER непонятно, все же напрямую приводится.
1. StartTime: Double;
ClockRate: Double;
надо было int64
2. весь класс поместить в implementaion
3. самое важное - hrdelay нагружает процессор. нужно sleep добавить при долгих (к примеру >0.1 сек) паузах.
1. да, не заметил
2. Нет, может пользователь для своих целей будет юзать, не только для delay
3. Ну, может он сделан для небольших пауз. Тогда будет излишнее усложнение.
>multimedia timers, не? чтоб процом-то не тормозить...
В винде (во всяком случае winXP) квант выделяемого задаче времени - 15мс. Так что задержку в 10мс не сделаешь никак, кроме такой вот жадной реализации.
>задержку в 10мс не сделаешь никак, кроме такой вот жадной реализации.
Да вот возмёт винда и вытеснит твой жадный слип на другую задачу... Так что это тоже не гарантия 10 мс
>Ну и приоритет по максимуму.
Ага, и приложение зависая - убивает всю ось до следующей перезагрузки ресетом... Конечные пользователи, вам это не простят.
"For example, a MIDI sequencer requires a high-resolution timer because it must maintain the pace of MIDI events within a resolution of 1 millisecond."
"Periodic timer events with an event delay of 10 milliseconds or less consume a significant portion of CPU resources." Но чувствую, что они примерно также сделаны.
В Дельфи надо 100 раз подумать, прежде чем лепить класс для какой-либо фигни. Потому что когда ты пишешь на Дельфи голыми структурами, то всё нормально, а как только ты переходишь на объекты, то надо ещё всё время думать о том, не забыл ли ты уничтожить объект, то есть сложность кода только увеличивается. Спасибо блять ботланду за ооп с ручными деструкторами. Я из-за этой поебени ваще забил на ООП в Дельфи.
Это спец.виртуал, чтобы обсирать Дельфи. Основной профиль марать не хочу.
Так вот, я за АВТОдеструкторы. А ручные деструкторы - это полный пиздец, кто только эту хероту придумал.
Тебя это не напрягает? Или ты не заботишься об исключениях, о том, что надо в каждой точке выхода прописать все вызовы деструкторов?
Не-не-не, нахуй такое ООП.
Не, ну если возвращать из функции объекты - это да, бред. Для этого есть конструкторы.
Я использую ООП для более-менее стабильных сущностей - всяких там групп приводов, существ, предметов и т.д. Для них я точно знаю, когда они должны создаваться и когда исчезать.
Да, слегка неудобно что я не могу прозрачно обернуть в объект скажем строку или set, но не отказываться же из-за этого от паскаля.
Да, всё есть. Язык вполне себе живёт, вот даже красноглазики для gcc сделали бесплатный компилятор Ады и среду. Правда, среда тоже красноглазая - немного не для людей сделана. Под винду есть версия, но с красноглазыми приколами - например, исходники сохраняет без 10го символа в переносах строк.
Не, что-то стремно. Паскаль кроссплатформенный (можно даже под андроид писать), для паскаля куча библиотек есть. А что автодеструкторов нет - ну да, чуток лишнего кода приходится написать, но это же не главное.
>Ага, на одной платформе один диалект, на другой - другой.
Один диалект (FreePascal) на все платформы. Ну и Дельфи на винде, слегка отличающимийся по фичам, зато с более эффективным компилятором.
>А сидеть на пороховой бочке тебя тоже не напрягает? Что программа может взять и потечь из-за того, что где-то какой-то случай не разобрал?
К моему стыду нет. Мой софт на спутники не ставят, а если возникает непредвиденное исключение (причем не один раз возникает, а начинает все время возникать, иначе меморилика серьезного не будет), то обычно виноват какой-нибудь баг в программе и утечка памяти становится наименее важной из бед.
>Ну передашь ты ссылку, у тебя объект сразу же скопируется (либо счётчик ссылок увеличится), какие проблемы?
и в результате не убьется. А его контейнер, к которому он относился уже убился, например. Так что когда этот обьект начнет удалятся, будет эксепшн. Хотя если правильно писать... может и не будет.
Вот для критических секций и файлов имхо и так все ясно. Один раз создали, один раз удалили. Если в локальной процедуре юзаем - обернули в try.
> и в результате не убьется. А его контейнер, к которому он относился уже убился, например
Так, иди изучай auto_ptr и shared_ptr, потом продолжи разговор. Это азы, объяснять их я не вижу смысла. Да и лень врубаться в то, что ты имеешь в виду.
> Вот для критических секций и файлов имхо и так все ясно. Один раз создали, один раз удалили.
А где именно удалили? А если из процедуры много выходов? Зачем руками следить за тем, для чего есть средства языка?
>Так, иди изучай auto_ptr и shared_ptr, потом продолжи разговор. Это азы, объяснять их я не вижу смысла. Да и лень врубаться в то, что ты имеешь в виду.
Я к тому, что всех проблем с памятью это само по себе не решит, все равно думать об области видимости надо.
>А где именно удалили? А если из процедуры много выходов? Зачем руками следить за тем, для чего есть средства языка?
В Аде - незачем, раз есть средства языка.
В Паскале - вполне нормально следить.
CS := TCriticalSection.Create;
try
... работаем с ней, можем вызывать exit сколько хотим
finally
CS.Free;
end;
Автодеструкторы сэкономили бы три строчки.
если программа написана с применением ООП, то сколько строчек сэкономлено - три строчки и сэкономлено. Критические секции я обычно создаю только в начале программы, а файлы открываю в одной-двух функциях.
>обернули в try.
Это ручная работа, а ты человек, а значит обязательно ошибешься. Мало того, что в софте будут ошибки, так ещё потом придется их отлаживать и тратить на это время. Лучше бы ты это доверил компилятору.
Это тупая работа, если это может сделать твой компилятор. Лучше ты за это время напишешь пару лишних программ, а значит больше заработаешь и уедешь на Карибы или просто будешь пинать балду, написав "недельную" программу за день, тк большую часть работы сделал за тебя компилятор..
>я успел бы написать на три-четыре строчки шаблонов больше.
А причём тут шаблоны, когда мы паттерн автодеструкторов обсуждаем и перекладывания работы на компилятор?
Я к тому, что эти несколько try..except мне много не сэкономят. Их написание и отладка - не больше 5% от общего объема. Тем более речь, кажется, об оборачивании в try критических секций и файлов? Тогда это 0.1%.
Что там можно отлаживать? В начале процедуры создал три объекта - в конце столько же объектов удалил. А большинство объектов все равно на куче создаются, и про них ты точно знаешь когда они появляются и когда умирают.
>меморилика серьезного не будет
Опасность не убитых объектов не только в утечках памяти, а в утечки прочих важных и не очень ресурсов и нарушениях логики работы программы.
Например, в многопоточном программировании используется паттерн:
При создании объекта - лочится семафор, а при удалении объекта - его отпускает. Это крайне удобно, тк не важно какое исключение бы не произошло - логика программы не нарушится, тк семафор все равно будет разблокирован при удалении объекта.
>обычно виноват какой-нибудь баг в программе
Вот, если бы часть работы компилятор языка делал за тебя, то баг бы такой может быть бы и не возник. Например он бы вызвал за тебя деструктор при исключениях или просто за тебя, даже когда ты бы забыл. В конце концов, проверил бы тип объекта или не меняешь ли ты константный объект.
>проверил бы тип объекта
Кстати, в дельфи это типичная ситуация, когда приходится использовать "безтиповый" pointer или variant или ещё какой хак, что-бы написать универсальную коллекцию. В то время, когда в языке есть шаблоны - коллекция может проверить во время компиляции тип элементов, которые в неё кладут.
Кстати, да, убится можно преобразовывать между char*, const std::string и std::string. А в Дельфи как раз все просто - всю работу менеджер памяти на себя берет.
выделение и освобождение памяти под хранение строк делает не сам менеджер, а тот код, где эти строки используются (он генерируется автоматом). в этой части все сделано как надо. проблема в самом менеджере памяти, но ее очень просто обойти - можно взять fastmem или написать свой велосипед через HeapAlloc / HeapFree - 20-30 строк кода.
В Дельфи строки и динмассивы встроены, для них всё автоматом делается как надо. Только они меня и спасают. Строки работают через счётчик ссылок, копируются при записи. Динмассивы - через счётчик ссылок, копируются только если прямо сказать.
А вот для остального почему-то ботланд не додумался сделать автодеструкторы. Зато он додумался в языке без ГЦ и автодеструкторов сделать классы, экземпляры которых создаются В КУЧЕ. Я считаю, что это рак мозга.
лол, у хабрабыдла всегда что-то глючить будет
альзо:
> Ошибка выскакивала
а коде говнище начинается уже с тупо скопипащенной венгерки
можно постить, воняет как треска
HRDelay() я написал для того, чтобы отмерять задержки до 1 мс. Всякие там Sleep(), GetTickCount() и пр. на таких интервалах имеют погрешность 1500% (тыщапицот!). Вот и всё. Основной код модуля взял с инета 100500 лет назад. Он работает, да и пох.
---
Ну и зачем 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массивы, что-бы у них деструктор сам вызывался? 😀
Но класть числа в динмассив длины 1 мне один раз пришлось.
Вообще это из моего калькулятора (архив с исходниками): http://tarasber.narod.ru/MiniCalc.rar
Функция взятия следующей лексемы из строки:
>narod.ru
your post gave me a feel
>Topacer
Торасег? Торасег? Да вам явно нужен ник антитарасег.
Я не Торасег. Я Топацер!
альзо:
> Ошибка выскакивала
а коде говнище начинается уже с тупо скопипащенной венгерки
можно постить, воняет как треска
ты - идиот, читай справочник, там черным по английскому написано почему погрешность и как с ней бороться.