+147
- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
var n = Math.abs(((date2 - date1) / 86400000) + 1);
var frac = n - Math.floor(n);
if (frac > 0.5) {
n = Math.ceil(n);
} else if (frac < 0.5 && frac.toPrecision(2) != 0) {
n = Math.floor(n);
n--;
}
n++;
Мой говнокод.
Задача: найти количество дней между двумя датами, включая сами эти даты. Время в датах сброшено в 0
Фишка в том "(date2 - date1) / 86400000) + 1", не работает когда есть перевод часов между двумя датами.
И вот такое говно я написал, которое по некоторым дням НЕ РАБОТАЕТ.
переписал вот так:
var n = Math.abs(date2 - date1);
n /= 3600000;
var mod = n % 24;
if (mod == 23) {
n++;
} else if (mod == 1) {
n--;
}
n /= 24;
n++;
теперь не важно сколько переводов часов прошло между датами: 0, 1, 2 или 5.
По поводу говнокода:
За такой frac на авторе надо зарабатывать фраг!
Oleg_quadro: автор, убей себя головой о клаву:
Oleg_quadro: "vb fgrbfvgr bgfvrt rtuijnikjikni56trg5rt6g45t6rgyh hnjunh ujuuuuuuuuuuuuuuuuuuuy"
Запостил:
Oleg_quadro,
01 Декабря 2010
и как это влияет на переводы часов?
var date2 = new Date(2010, 4, 28);
console.log(Math.abs(date2 - date1)/86400000);
87.95833333333333
разве JS не интерпретируется в большинстве своих реализаций?
javascript для ускорения
jit-компиляция.
http://www.linux.org.ru/news/mozilla/4600049
и не только в FF!
еще бы меморилики починил в FF -- цены бы мозиле не было
А потом ты её очистишь, а памяти сколько жрала прога, столько и жрёт.
Не встречал прогу, которая память бы отдавала.
(при том не важна какая ОС - Виндоус или Линукс).
Видно ОС не узнать, что ты не используешь какой-то кусок памяти.
Но есть, правда, откровенные ошибки программирования, когда памяти отжирается всё больше и больше.
это если я не умею делать free (в сях) или delete (в с++).
>>Не встречал прогу, которая память бы отдавала.
хм))
>>Видно ОС не узнать, что ты не используешь какой-то кусок памяти.
man free же!
>>Но есть, правда, откровенные ошибки программирования, когда памяти отжирается всё больше и больше.
есть! это и есть мемори лик.
<captain mode>
Мне всегда казалось, что дело обстоит так:
Когда программа хочет взять у операционки память -- она говорит malloc. Операционка дает ей память (или не дает, если память кончилась). Менеджер памяти в операционке считает эту память занятой. Потом программа понимает, что память ей больше не нужна, и делает ей free. Тоесть отдает ее опять операционке.
Если не сделать free -- память утечет. В плохих или сложных программах не всегда понятно когда можно сделать free (вдруг память еще кем-то используется?). Криворукие программисты не всегда делают free, и потому все больше и больше отжирают памяти.
Для шаред мемори есть другие механизмы (HeapDestroy в винде, MM_free в линухах итд)
Но идеология одна: взял память, поюзал, понял что больше не надо, отдал.
В платформах с GC (jvm (жаба), clr/.net итд) память освобождает GC, когда видит что на нее не осталось ссылок (транзитивно или напрямую) из стеков вызовов потоков и из пермген (всякие статик свойства классов итд). Тоесть когда память больше никому не нужна. Что бы программа утекла памятью -- надо копить ссылки и не отдавать их. Сделать утечку памяти в программе с GC сложнее, но тоже можно.
FF пишут на C++, и видимо не всегда делают delete (_в данном контексте_ плюсовый аналог free) :)
</captain mode>
и delete — тоже.
В том-то вся и штука.
2) т.е. она может быть переиспользована только в рамках этого же процесса?
2) да.
написал прогу на си. такую: ( в си не силён, не программирую в нём)
#include <stdio.h>
#include <stdlib.h>
int main(void) {
char *str;
str = (char *) malloc(10);
printf ("%s", "Input\n");
gets(str);
//====================
char *s;
s = (char *) malloc(1000000000);
printf ("%s", "Input\n");
gets(str);
free(s);
printf ("%s", "Input\n");
gets(str);
free(str);
}
и на перле такую:
#!/usr/bin/perl
use strict;
<>;
my $str = "1" x 100000000;
<>;
$str = "";
<>;
Вообщем смысл прог в том.
0)запускаются,
1)запрашивают ввод с клавы,
занимают кучу памяти,
2)потом опять запрашивают ввод с клавы,
освобождают переменные.
3)запрашивают ввод с клавы,
выход
в другом окне смотрел топ:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
27788 user 17 0 11532 928 800 S 0.0 0.0 0:00.00 da.o /*запустили*/
27788 user 15 0 964m 940 804 S 0.0 0.0 0:00.00 da.o /*отожрали кучу памяти*/
27788 user 15 0 11532 940 808 S 0.0 0.0 0:00.00 da.o /*освободили память*/
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
28046 user 17 0 77896 1560 1216 S 0.0 0.0 0:00.00 perl da.pl /*запустили*/
28046 user 16 0 266m 192m 1220 S 7.3 4.1 0:00.22 perl da.pl /*отожрали кучу памяти*/
28046 user 15 0 266m 192m 1220 S 0.0 4.1 0:00.22 perl da.pl /*освободили память*/
p.s почему проги имеют название "da"? да так от балды назвал
то есть перл не отдал. и заметьте, что только виртуальная память отожралась. надо сделать ещё один эксперемент, где бы отжиралась обычная бы память.
правда, он там reference counting вроде бы.
а что такое "обычная память"? невыгружаемая что ли?
вообщем модифицировал прогу,
добавил memset(s, 'A', 1000000000).
реальная память стала отжираться, но после очищения переменной, память сбросилась в 0.
провёл эксперемент: сделал такую html-ную страничку:
Открывал её в разных браузерах, в Винде (XP):
и смотрел в диспетчер задач:
слева память, справа виртуальная память:
IE
27 512, 22 112
657 604, 651 584/*отожрали кучу памяти*/
657 620, 651 616/*очистили переменную*/
Хром
27 704, 16 452
28 240, 16 736/*отожрали кучу памяти*/
28 264, 16 748/*очистили переменную*/
FF
81 936, 65 824
102 268, 85 228/*отожрали кучу памяти*/
100 792, 84 020/*очистили переменную*/
P.S. память немного колеблется туда-сюда в Диспетчере задач: через секунду на 1 кб больше, потом ещё через 1 на кб меньше.
во-первых всякая память все равно виртуальна (при соответствующем режиме процессора).
во-вторых операционка сама решает -- что выгружать на диск, а что -- нет.
в винде есть невыгружаемая память -- с ней работают драйверы, которые выставляют такой IRQL, что PageFault не может случится (вернее случится IRQL_NOT_LESS_OR_EQUAL), и считать память с диска некому. Но это в кернел спейсе.
Приложения вроде не могут выбирать что будет с их памятью))
Оказывается если открыть одну вкладку, то показывается 3 процесса chrome.exe. Я видимо смотрел другой процесс.
Я переделал тест:
Вот данные по Хрому:
13 712, 8 804
218 996, 213 468/*отожрали кучу памяти*/
219 092, 213 472/*очистили переменную*/
Всё, щас здесь не сразу появлюсь, пойду поработаю.
проведите эксперемент на java, например.
не знаю.
J2EE проклятое совсем меня обезънит))
Вся работа с деревьями и связными списками обёртывается в объект, и всё - автоматическое управление. Конечно, можно облажаться при написании дерева, но лажа будет сосредоточена внутри одного модуля и легко обнаруживаема. И вообще, все такие структуры уже написаны до нас.
в плюсах не силен, но попытаюсь:
вопрос: как (без использования GC) понять, когда удалить manager и user?
Если в С++ это тоже самое, но я не понимаю, как это поможет.
Это поможет тем, что в потерянной паре (A, B), ссылающейся на себя, одна из ссылок не влияет на счётчик. То есть один из объектов пары будет иметь нулевой счётчик ссылок сразу в в момент потери пары и потащит за собой всю цепочку на удаление.
Главное, чтобы все объекты были выстроены по порядку, указатель, ведущий на класс, объявленный ранее - сильный, на ещё не объявленный - слабый. Указатели на себя - слабые.
Да, возможны потерянные слабые указатели, но всё работу с подобными сущностями надо обёртывать.
Вот от этого-то и избавляет GC. А еще он избавляет от фрагментации.
Так что я не стал бы называть его говном.
Но за все надо платить. В случае GC мы платим невозможностью ручного удаления объекта, переодическими тормозами при запуске GC, и невозможностью использования деструкторов (потому что хз когда они вызовуца).
GC конечно разжижает мозг, но в случае энтерпрайза (когда памяти и цпу много) вполне себя оправдывает
ps: счетчик ссылок у класса уменьшается транзитивно?
тоесть когда из стека уходит объект -- уменьшается счетчик у него и у всех , на кого он ссылается, верно?
Да.
> нужно выстраивать объекты по порядку итд.
На самом деле можно делать всё просто - указатель на то, что ещё не объявлено (в т ч на себя) - слабый, а указатель на то, что уже объявлено - сильный.
Вот посмотри на те же динмассивы из дельфей (которые автодохнут). Их можно задавать только из уже объявленных сущностей. Но элемент динмассива может содержать простой (слабый) указатель на структуру, содержащую динмассив и через него ссылаться на родителя.
Если в такой схеме запретить вообще операцию new для слабых указателей, то утечки станут исключены вообще! Но будут небольшие проблемы с реализацией деревьев, для них надо оставить возможность делать new для слабых указателей. Желательно, чтобы для этого была отдельная прагма, которая принудительно разрешает это делать, и которой пользоваться считается чем-то опасным, как сейчас считается опасным пользоваться асмом.
Короче, ГЦ не нужен.
Кстати, в затяжном сраче ставить минусы кому-либо - школьный тон.
судя по тому что я последний раз вычитал - в мозилле не признают этот баг (вероятно не могут найти где течёт)
чем память заполнена хотя бы?
в мире жабы и дотнет так делают (смотрят на кучу профайлером типа yourkit или dotTrace)
поэтому максиму на что способен - прочитать страничку о багах и кратко изложить в комментах на другом сайте
var date2 = new Date(2010, 4, 28);
console.log(Math.abs(date2 - date1)/86400000);
//87.95833333333333
var date1 = new Date(2010, 2, 1);
var date2 = new Date(2010, 10, 28);
console.log(Math.abs(date2 - date1)/86400000);
//272
var date2 = new Date(2010, 2, 28);
console.log(Math.abs(date2 - date1)/3600000);
//24
var date1 = new Date(2010, 2, 28);
var date2 = new Date(2010, 2, 29);
console.log(Math.abs(date2 - date1)/3600000);
//23
то есть Date - это локальное время с часовым поясом.
вот если бы был второй глобальный объект Date (это объект в JS, не класс, если не знаете (в нём ваще классов нет)) без переводов часов было бы круто.
01 Dec 2010 00:00:00 и 01 Dec 2010 22:30:00,
01 Dec 2010 00:00:00 и 01 Dec 2010 23:00:00,
01 Dec 2010 00:00:00 и 01 Dec 2010 23:30:00,
01 Dec 2010 00:00:00 и 02 Dec 2010 00:00:00,
01 Dec 2010 00:00:00 и 02 Dec 2010 00:30:00,
01 Dec 2010 00:00:00 и 02 Dec 2010 01:00:00,
01 Dec 2010 00:00:00 и 02 Dec 2010 01:30:00?
Почему?
полезно выкладывать свое решение на говнокод.