Страницы

Поиск по вопросам

воскресенье, 21 октября 2018 г.

Какой формат быстрее всего распарсится?

Есть кучка данных. Нужно их обработать, переработать и сохранить. Время на переработку - не особо лимитируется. Потом в какой-то момент их нужно максимально быстро считать и отдать. В каком формате их хранить? Т.е. скорость создания файла не важна, а скорость считывания нужна на максимально быстром уровне Размер тоже не важен UPD1 Пока склоняюсь к MessagePack и csv. Итого: CSV


Ответ

О боже, век XML и JSON. Все забыли о бинарных форматах? Быстрее всего - бинарный с полями фиксированной длинны. Вариация на тему DBF, к примеру. Из тех нужно парcить - простой это CSV, к примеру.

Java: объясните поведение компилятора

Здравствуйте! Столкнулся со странным поведением компилятора, объясните пожалуйста, почему происходит вывод разных строк. class EntityModel{ public String name; public EntityModel(){ this.name = "EntityModel"; } public String getName(){ return this.name; } } class Model1 extends EntityModel{ public String name; public Model1(){ this.name = "Model1"; }
@Override public String getName(){ return this.name; } } Вызов: EntityModel m = (EntityModel)new Model1(); System.out.println(m.name); System.out.println(m.getName()); Вывод: EntityModel Model1 Код на ideone.com Почему обращение к полю на прямую и через геттер дают разные результаты?


Ответ

Хе :) Если коротко, то в Java методы виртуальные, а поля — нет. То есть, привязка метода к имени метода производится на этапе выполнения в соответствии с настоящим, динамическим типом объекта, а вот привязка поля — статическая, производится на этапе компиляции. Так сделано потому, что выставлять наружу открытое поле всё равно очень плохая практика, поэтому доступ к полям можно ускорить за счёт точного определения поля во время компиляции. А вот вызывая публичный метод, программист не ожидает вызова не самого «свежего» метода, так что здесь логичнее виртуальный вызов. (Впрочем, архитекторы C# считают не так, но это уже вопрос дизайна языков.) Это всё ещё один аргумент к тому, чтобы делать все поля private, и получать доступ к ним лишь через getter.

Зачем использовать Spring?

Я имею в виду основную функциональность. Я, в общем-то, понял концепцию IoC и DI. Но какие это действительно дает преимущества? Только ли возможность с легкостью сменить одну реализацию класса на другую и не писать везде new? Нигде не нашел прямо прозрачного примера достоинств Spring-а, везде с первого абзаца про общий принцип IoC.


Ответ

Основное преимущество Spring'а - возможность разработки приложения как набора слабосвязанных (loose-coupled) компонентов. Чем меньше компоненты приложения знают друг о друге, тем проще разрабатывать новый и поддерживать существующий функционал приложения. Классический пример - управление транзакциями. Spring позволяет вам управлять транзакциями совершенно независимо от основной логики взаимодействия с БД. Изменение этой логики не порушит транзакционность, равно как изменение логики управления транзакциями не сломает логику программы*. Spring поощряет модульность. Компоненты можно добавлять и удалять (почти) независимо друг от друга. В принципе, приложение можно разработать таким образом, что оно даже не будет знать, что управляется Spring'ом*. Также Spring заметно упрощает модульное тестирование (unit-testing): в компонент, разработанный для работы в IoC контейнере очень легко инжектировать фейковые зависимости и проверить работу только этого компонента. Ну, и в качестве приятного дополнения, Spring сильно облегчает инициализацию и настройку компонентов приложения, позволяя гибко настраивать приложение без существенных изменений Java-кода*.
Ещё раз, кратко:
Поощрение слабой связанности компонентов, и, как следствие... ... упрощение инициализации и настройки компонентов, ... упрощение модульного тестирования, ... упрощение разработки и поддержки приложения в целом.
* Читая эти предложения, делайте скидку на уровень профессионализма программистов, использующих фреймворк. Всегда можно что-нибудь сломать или неоптимально организовать, но в умелых руках Spring весьма эффективен.

export/extern&шаблоны

Интересно, почему export шаблонов deprecated? Знаю только то, что никто не реализовал ее в своих компиляторах кроме компании Edison Design Group, но потом и они признали что это полная "лажа". В чем были сложности?
В новом стандарте, вместо export tempate ввели extern template. Зачем? Некрофилия?


Ответ

Проблема следующая. Шаблоны C++ — функциональность, гораздо более близкая к макросам, чем к функциям/классам. Это чистая конструкция времени компиляции. Невозможно «скомпилировать» шаблон так, чтобы потом можно было просто подлинковать его к программе (в отличие от функций и классов.) Поэтому хранить в объектном файле всё равно придётся текст, никакого выигрыша это не даст.
Почему невозможно заранее скомпилировать шаблон в объектный код? Посмотрите на вот такой простой код:
template void f(T1 t1) { T2 t2 = t1; }
Это копирующая инициализация. В зависимости от типов T1 и T2, а также от видимости других типов в точке использования она может компилироваться в вызов наилучшего из доступных конвертирующего конструктора (и преобразование типа T2 к типу аргумента этого конструктора, если они не совпадают), оператора конверсии, стандартные конверсии, числовые конверсии, включая потерю точности и смену представления между плавающей точкой и целыми числами.
Как вы думаете, можно ли закодировать всё это в объектном коде (то есть, по существу на ассемблере), не зная на момент компиляции типы T1 и T2?

Вот есть целая статья от EDG, с анализом, почему экспорт шаблонов не взлетит и не стоит свеч: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1426.pdf. И ещё одна: http://blogs.msmvps.com/vandooren/2008/09/24/c-keyword-of-the-day-export/
Более подробно, проблемы следующие (перевёл из статьи EDG):
У EDG на одну эту фичу ушло 1,5 лет на дизайн и 3 года на имплементацию (сравнение: на всю Джаву — только два года). При этом EDG — не «какая-то» компания, у них хорошие разработчики, с многолетним опытом разработки компиляторов C++. Типичная структура компилятора C++ не подходит для имплементации этой фичи. Пришлось переделывать дизайн компилятора, и скорее всего это же придётся сделать всем другим разработчикам, если экспорт станет обязательной частью стандарта. Многие ошибки, которые без экспорта шаблонов было не обязательно детектировать (например, нарушение ODR-rule, которое по стандарту всего лишь UB), с экспортом фактически становится обязательно отлавливать. Форматы промежуточных файлов придётся полностью менять. Эта фича не приносит настолько уж большой пользы:
Считается, что с экспортом шаблонов более не нужно будет поставлять исходный код библиотек. Это не так. Поскольку шаблоны работают на уровне, близком к синтаксическому, то вместе с библиотеками придётся поставлять либо текст шаблонов, либо его прямой эквивалент (например, синтаксическое дерево), поскольку во время инстанциации шаблонов нужна вся эта информация. Считается, что с экспортом шаблонов ускорится компиляция и уменьшится количество зависимостей. Это не так, потому что (вследствие синтаксической природы шаблонов) экспортированный шаблон невозможно заранее скомпилировать. Компиляцию шаблона (по меньшей мере от уровня синтаксического дерева) придётся всё равно повторять, на этот раз на этапе компоновки. Таким образом, компилятору придётся выполнить по меньшей мере ту же работу, что и без экспорта. Единственный реально сработавший плюс экспорта шаблонов — то, что макросы не покидают границы единицы трансляции. (В случае без экспорта, макросы, определённые в файле с шаблоном, «видны» всем, кто использует шаблон.) Этого положительного эффекта, однако, можно добиться при помощи более строгой организации кода; также существуют другие, более лёгкие и эффективные методы решения этой проблемы на уровне стандарта языка.

javascript, замыкания, проблемы синтаксиса

Есть код на JavaScript:
"use strict";
var site = (function () { var loader_html = ''; var loader_image_width = 100; var loader_image_height = 100;
return { window_subroutines : { get_scrollTop : function () { return (document.documentElement && document.documentElement.scrollTop) || (document.body && document.body.scrollTop); }, get_scrollLeft : function () { return (document.documentElement && document.documentElement.scrollLeft) || (document.body && document.body.scrollLeft); }, get_clientWidth : function () { return (document.documentElement && document.documentElement.clientWidth) || (document.body && document.body.clientWidth); }, get_clientHeight : function () { return (document.documentElement && document.documentElement.clientHeight) || (document.body && document.body.clientHeight); } },
loader : { show : function () { var loader_elem = document.getElementById ("loader_container"); var left_coord = Math.round(site.window_subroutines.get_scrollLeft() + ( site.window_subroutines.get_clientWidth() / 2 ) - ( loader_image_width / 2 )) + "px"; var top_coord = Math.round(site.window_subroutines.get_scrollTop() + ( site.window_subroutines.get_clientHeight() / 2 ) - ( loader_image_height / 2 )) + "px";
loader_elem.innerHTML = loader_html; loader_elem.style.top = top_coord; loader_elem.style.left = left_coord;
loader_elem.style.display = "block"; },
hide : function () { setTimeout("document.getElementById('loader_container').style.display = 'none';", 750); } } };
})();
Проблема в том, что при попытке его выполнить браузер выводит ошибку:
SyntaxError: function statement requires a name get_scrollTop : function () { return (document.documentElement && document.docum...
Посмотреть живьём это можно на jsfiddle


Ответ

Надо изменить
return {
на
return {
JavaScript добавляет в конец строка автоматическим образом, так что код распарсится так:
return; { // блок кода window_subroutines: // метка { // блок кода get_scrollTop : // метка function () { /* ... */ } // SyntaxError: декларация функции без имени
(Смотрите в спецификации о инструкциях с метками и автоматической подстановке точки с запятой)

FreeBSD gcc install

Здравствуйте. Стараюсь поставить на FreeBSD 7 x64 gcc посвежее родного 4.2.1. Из портов не ставится. Жалуется на отсутсвие GMP и MPFR (или их кривой путь). По этому ответу поставил нужные библиотеки и с их помощью конфигурил make, который потомвыдавал:
Error expanding embedded variable. Error code 2
Пробовал так же по вышеуказанному ответу собирать gmake'ом, но процесс съедает всю оперативку, и завершается:
virtual memory exhausted: Cannot allocate memory gmake[2]: *** [insn-recog.o] Error 1 gmake[2]: Leaving directory `/root/tmp/gcc-4.9.1/host-x86_64-unknown-freebsd7.2/gcc' gmake[1]: *** [all-gcc] Error 2 gmake[1]: Leaving directory `/root/tmp/gcc-4.9.1' gmake: *** [all] Error 2
Прошу помочь разобраться с этим вопросом.


Ответ

Как насчет дополнительного свапа? Создайте файл нужного размера при помощи dd
dd if=/dev/zero of=/usr/swap0 bs=1m count=64
Затем его нужно разметить как swap
mkswap /usr/swap0
И задействовать
swapon /usr/swap0

Как узнать, есть ли обработчик на теге?

Есть тег. При клике он открывает одну шторку, но я не можу найти обработчик клика на нем в js.
Есть ли какой то способ найти этот оброботчик через инструменты разроботчика?


Ответ

Если речь идет именно об инструментах разработчика, то в Хроме делаем так:
Кликаем правой кнопкой мыши по нужному элементу => Inspect element (или же F12, а затем находим и выделяем нужный элемент в дереве). Далее в правой нижней колонке есть вкладка Event Listeners, там можно найти все обработчики. Соответственно для клика ищем событие click. Если необходимо найти только обработчики событий текущего элемента, снимаем галочку Ancestors, если же возможно, что клик идет по какому-то родителю (что довольно часто бывает), то галку оставляем.