Showing posts with label glib. Show all posts
Showing posts with label glib. Show all posts

Saturday, January 10, 2009

Производительность vs удобство интерфейса

На выходных я добавил к своему игрушечному браузеру поддержку контента записанного прямо в страницу, то есть вида когда источником ставится data:image/png..... При этом заменил способ работы с файловой системой на использование gio. Это стандартный компонент в новых версиях glib для доступа к ресурсам и при установке в систему плагин позволяющий в зависимости от плагинов работать с файлами (file:) и сетью (http:,smb:,https:) через унифицированный интерфейс и все типы контента отображаются одинаково для программы.

Я использую эту библиотеку только для получения данных по умолчанию, если все остальные способы определенные мной не смогли отработать запрос. Причиной этого послужило:
  • что реализации плагина для data:... я не искал - текущая реализация как по мне вполне сгодиться;
  • а вот для http использовать реализацию плагина по умолчанию нельзя так у меня есть хоть частичная реализация работы с cookies(очень плохая: просто объединение всех cookies полученных за сесию в одну строку и отсылку на все страницы);
  • и что более важно отсутствие логики работы с относительными путями для случаев не файл(по коду все относительные пути берутся начиная с пути места запуска приложения) - и как результат я использую свою реализации обработки относительных путей - пока неверную, но надеюсь когда нибудь доделаю.
Благодаря реализации интерфейса доступа к ресурсам основанном на создании потоков потерялась возможность использовать возможность системы отображать файлы в память. Отображать то можно, но смысла мало, так как в вызовах используется указание области памяти куда нужно сохранить и потом можно спокойно вызвать освобождение. При этом, если нам удалось отобразить файл на какую-то область мы должны(в зависимости от реализации) вызвать unmap перед освобождением участка. Хотя в linuх - может сработать: Normally, malloc() allocates memory from the heap, and adjusts the size of the heap as required, using sbrk(2). When allocating blocks of memory larger than MMAP_THRESHOLD bytes, the glibc malloc() implementation allocates the memory as a private anonymous mapping using mmap(2). Но лучше не играться с этим.

Если использовать после отображения копирование данных - то мы получим стандартные вариант read,write - и увеличения производительности не будет.

В glib есть обертка над mmap - gmappedfile, но mmap используеться только для MIMEINFO - xdgmimecache.c

Пока абстракция интерфейса побеждает.

PS: Хотя в общем тенденция хорошая - мало приложений использует отображение, и еще меньшему количеству он реально нужен. А так мы получаем простой унифицированы интерфейс доступа.

Monday, December 22, 2008

Сборка мусора

Или GC(Garbage Collection) применимо к glib.

В glib относительно памяти есть договоренность, что если возвращается константный указатель. то его освобождать не нужно, а в обратном случае нужно. Так же для gobject существуют функции g_object_ref () и g_object_unref (). Это решает проблему с слежением за выделением памяти, но требует от разработчика чтобы он следил за выделением памяти и при каждом копировании указатяля делал соответствующий вызов ref/unref. Что не совсем удобно... Система автоматической сборки мусора в C# или Java более удобна, но требует соответствующей поддержки от компилятора. Хотя эта проблема решена в Vala, так как он автоматически добавляет вызовы удаления памяти в чистом виде в glib его нет.

Моя идея - добавить систему(на начальном этапе только для отладки): при каждом выделении памяти запоминать, где она была выделена(строка , файл и можно еще идентификатор потока) и к какому объекту привязана(области памяти) - затем при удалении удалять эту привязку, чтобы при вызове удаление родительского объекта можно было посмотреть какие области памяти остались не освобожденными и где их выделяли. В общем случае получается структура в виде дерева, где к каждому узлу(области памяти) привязывается привязывается список областей памяти выделенных для подчиненных по отношении к нему ресурсов и где они выделялись.

Отличие он настоящей сборки мусора - автоматически память не освобождается, только добавляется код отладки освобождения чтобы можно было посмотреть где выделялось. Очищать память автоматически не удастся(нужно придумывать систему макросов), что в общем случае делать не хочется или изменять компилятор. Оптимизация размещения объектов в памяти для glibc несколько теряет смысл так как все изменения указателей отслуживать сложно и нужно изменять код чтобы с непосредственно с указателями никто не работал и как-то выделял все ссылки в объектах чтобы можно было менять их расположение - что скорее всего особого смысла не имеет.

И по моему реализации системы отслеживания как инструмента отладки более перспективна и удобна. В дальнейшем сюда можно добавить и код регистрации открытия - закрытия файловых потоков

Маленькое примечание: настоящие системы сборки мусора - следят за созданием объектов и при уходе из области видимости объект отмечается как такой который можно удалять и если не него уже нет ссылок он удаляется, также при сборке мусора объекты перемещаются для избежания фрагментации памяти и нужные ссылки модифицируются.

Sunday, December 21, 2008

Изменения к gtkhtml

Мои изменения к gtkhtml частично внесли в основную ветвь. Частично - так как по умолчанию компонент ведет себя в режиме совместимости со старым поведением и старается никак не выделятся. Также обнаружился маленький дефект с памятью - при замене спец символов после перекодировки я сдвигал текст в буфере на освободившееся место, что в общем может дать снижение скорости обработки, если спецсимволов много и сдвиг не оптимизирован для случая перекрытия источника и приемника(то есть именно для этого случая).

Мои изменения(уже примененные) позволяют при отображении страницы, если указан не корректный контент тайм, сменить его и отобразить оставшуюся страницу нормально. Также я добавил в зависимости от контент тайпа возможность перекодировать параметры запросов с форм. По умолчанию эта логика отключена, так как evolution сам перекодирует сообщение перед отображением, но не удаляет из сообщения не корректную кодировку и компонент не может правильно отобразить сообщение - изменить код в evolution не удалось, так как он достаточно запутанный(или это мне только показалось).

Пока не применены мои изменения относительно замены функции получения кода спецсимвола по его имени через автоматически сгенерированную hash функцию(gperf) и замена ранее указанного перемещения(сдвига памяти) на использование 2 буферов.

В дальнейшем gtkhtml в evolution(по планам) будет заменен на WebKit и если планы не изменяться, то развитие проекта будет прекращено. А пока я подправил также и свой миниброузер ради которого и были сделаны эти изменения.