1. JavaScript / Говнокод #4802

    +147

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 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

    Комментарии (67) RSS

    • http://skepticalteacher.files.wordpress.com/2009/10/facepalm1.jpg
      Ответить
    • автор бредит что ли?
      и как это влияет на переводы часов?
      Ответить
      • var date1 = new Date(2010, 2, 1);
        var date2 = new Date(2010, 4, 28);
        console.log(Math.abs(date2 - date1)/86400000);
        87.95833333333333
        Ответить
      • не бредю.
        Ответить
        • Перевод часов тут никак не учитывается, если только он не зашит в операцию вычитания компилятора.
          Ответить
          • >>операцию вычитания компилятора.
            разве JS не интерпретируется в большинстве своих реализаций?
            Ответить
            • Спасибо, исправлю: s/компиля/интерпрета/g
              Ответить
            • сейчас есть новая технология в браузерах, которая компилирует код
              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>
                    Ответить
                    • free очищает память, но не отдаёт обратно ОС!
                      и delete — тоже.
                      В том-то вся и штука.
                      Ответить
                      • 1) что значит "очищает"?
                        2) т.е. она может быть переиспользована только в рамках этого же процесса?
                        Ответить
                        • 1) это значит, что новое выделение памяти, может быть как раз на этом месте.
                          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"? да так от балды назвал

                              то есть перл не отдал. и заметьте, что только виртуальная память отожралась. надо сделать ещё один эксперемент, где бы отжиралась обычная бы память.
                              Ответить
                              • в перле же есть gc, может он не очистил еще?
                                правда, он там reference counting вроде бы.

                                а что такое "обычная память"? невыгружаемая что ли?
                                Ответить
                                • я имел в виду, ту которая реально в оперативной памяти (столбец МЕМ в top)
                                  вообщем модифицировал прогу,
                                  добавил memset(s, 'A', 1000000000).
                                  реальная память стала отжираться, но после очищения переменной, память сбросилась в 0.

                                  провёл эксперемент: сделал такую html-ную страничку:

                                  <script>
                                  var js = '';
                                  alert(1);
                                  for (var i = 0; i <= 10000000; i++) {
                                  	js += 'a';
                                  }
                                  alert(1);
                                  js = '';
                                  </script>


                                  Открывал её в разных браузерах, в Винде (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 -- говно, и я сам руками все сделаю. Он делал все более и более сложные конструкции для управления памятью, и в конце концов родил свой GC)
                        Ответить
                        • GC - говно, все конструкции для управления памятью уже встроены в С++, только надо их использовать, а не использовать char* вместо std::string чисто из принципа.
                          Ответить
                          • и что они сделают с islands of isolation, например?
                            Ответить
                            • Они просто не будут их создавать.
                              Вся работа с деревьями и связными списками обёртывается в объект, и всё - автоматическое управление. Конечно, можно облажаться при написании дерева, но лажа будет сосредоточена внутри одного модуля и легко обнаруживаема. И вообще, все такие структуры уже написаны до нас.
                              Ответить
                              • причем тут структуры?

                                в плюсах не силен, но попытаюсь:
                                /*Дерьмовый метод, никогда так не делайте))*/
                                CUser* CreateManager() {
                                 CUser* client, manager;
                                 user = new CUser;
                                 manager = new CManager;
                                
                                 user->setManager(manager);
                                 manager->setUser(user);
                                 return manager;
                                }

                                вопрос: как (без использования GC) понять, когда удалить manager и user?
                                Ответить
                                • Для юзер->манагер использовать слабый указатель.
                                  Ответить
                                  • У нас в жабе слабый указатель это такой враппер, который позволяет объекту удалится, а если он удален -- возвращает null.

                                    Если в С++ это тоже самое, но я не понимаю, как это поможет.
                                    Ответить
                                    • Слабый указатель - указатель, работа с которым не влияет на счётчик ссылок.
                                      Это поможет тем, что в потерянной паре (A, B), ссылающейся на себя, одна из ссылок не влияет на счётчик. То есть один из объектов пары будет иметь нулевой счётчик ссылок сразу в в момент потери пары и потащит за собой всю цепочку на удаление.
                                      Главное, чтобы все объекты были выстроены по порядку, указатель, ведущий на класс, объявленный ранее - сильный, на ещё не объявленный - слабый. Указатели на себя - слабые.
                                      Да, возможны потерянные слабые указатели, но всё работу с подобными сущностями надо обёртывать.
                                      Ответить
                                      • Тоесть мне все время прихожится думать о памяти: нужно помнить что указатель должен быть weak, нужно выстраивать объекты по порядку итд.

                                        Вот от этого-то и избавляет GC. А еще он избавляет от фрагментации.
                                        Так что я не стал бы называть его говном.

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

                                        GC конечно разжижает мозг, но в случае энтерпрайза (когда памяти и цпу много) вполне себя оправдывает

                                        ps: счетчик ссылок у класса уменьшается транзитивно?
                                        тоесть когда из стека уходит объект -- уменьшается счетчик у него и у всех , на кого он ссылается, верно?
                                        Ответить
                                        • > счетчик ссылок у класса уменьшается транзитивно?

                                          Да.

                                          > нужно выстраивать объекты по порядку итд.

                                          На самом деле можно делать всё просто - указатель на то, что ещё не объявлено (в т ч на себя) - слабый, а указатель на то, что уже объявлено - сильный.
                                          Вот посмотри на те же динмассивы из дельфей (которые автодохнут). Их можно задавать только из уже объявленных сущностей. Но элемент динмассива может содержать простой (слабый) указатель на структуру, содержащую динмассив и через него ссылаться на родителя.
                                          Если в такой схеме запретить вообще операцию new для слабых указателей, то утечки станут исключены вообще! Но будут небольшие проблемы с реализацией деревьев, для них надо оставить возможность делать new для слабых указателей. Желательно, чтобы для этого была отдельная прагма, которая принудительно разрешает это делать, и которой пользоваться считается чем-то опасным, как сейчас считается опасным пользоваться асмом.
                                          Короче, ГЦ не нужен.
                                          Ответить
                                          • Ололо набижал пубертант не осиливший работу с памятью и заминусовал меня.
                                            Ответить
                                            • Да и фраза "GC говно" тоже не очень по взрослому звучит, честно-то говоря)
                                              Ответить
                                              • Фраза "ГЦ не нужен" чем не нравится?
                                                Кстати, в затяжном сраче ставить минусы кому-либо - школьный тон.
                                                Ответить
                    • кэп слишком упростил, забыл про диспетчера кучи и был разжалован в сержанты.

                      судя по тому что я последний раз вычитал - в мозилле не признают этот баг (вероятно не могут найти где течёт)
                      Ответить
                      • а нельзя как-то по дампу память понять -- где течет?
                        чем память заполнена хотя бы?

                        в мире жабы и дотнет так делают (смотрят на кучу профайлером типа yourkit или dotTrace)
                        Ответить
                        • в мои планы не входит думать о самостоятельной починке мозиллы, если вы на это намекаете :р
                          поэтому максиму на что способен - прочитать страничку о багах и кратко изложить в комментах на другом сайте
                          Ответить
                • можешь провести эксперимент на Перл, если хочешь.
                  Ответить
          • var date1 = new Date(2010, 2, 1);
            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 date1 = new Date(2010, 2, 27);
            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?

          Почему?
          Ответить
    • [url="yandex.ru"]test[/url]
      Ответить
    • TEST
      Ответить
    • Ай, не топите! Хотя... можно, я сохранил.
      Ответить
      • Всё говно сохраняете? Туалет тогда Вам лучше сдавать соседям.
        Ответить

    Добавить комментарий