Поддержание программного кода в приличном состоянии зачастую является непростой задачей. Безусловно, существуют различные процедуры и техники для этого, начиная от руководств стиля (style guide), которым должны следовать разработчики, заканчивая статическими
анализаторами и строгой инспекцией кода (code review).
В данной работе нас интересует класс приложений, в которых используются реляционные базы данных. Не у каждого программиста есть отчётливое представление о работе с системами управления базами данных. Тестируя программный код на небольших объёмах данных,
разработчик может получить впечатление, что работа с СУБД практически не отличается от работы с коллекцией объектов в оперативной памяти. Широко используемая парадигма объектно-ориентированного программирования и различные Object Relational Mapping-библиотеки
хорошо вписываются в теорию «идеального» кода, но на практике, на
реальных объёмах данных, такое слепое следование общепризнанным
концепциям программирования может создать значительные проблемы с производительностью, что можно видеть в работах [1] и [2]. Мы хотим проектировать приложения так, чтобы работа с базами данных была эффективна. Как этого добиться? Об этом и пойдёт речь далее.
Рефакторинг – неотъемлемая часть культуры программирования, и
подразумевает как рутинные задачи, так и сложную интеллектуальную аналитическую работу. Многие разработчики ищут золотую середину между идеальным кодом и «техническим долгом». Таким образом, тема автоматического рефакторинга набирает всё большую популярность в виду роста объёма исходного кода приложений.
Мы задались вопросом, можно ли каким-то способом повысить эффективность взаимодействия с БД, не переписывая приложение «с нуля». Различные среды разработки, такие как IDEA и Eclipse предлагают мощные инструменты для рефакторинга кода, но они не касаются
анализа и оптимизации фрагментов кода, содержащих SQL-запросы. В виду отсутствия подобных решений, было решено исследовать возможность анализа и автоматического рефакторинга вычислительно неэффективных фрагментов программного кода.
В связи с тем, что наша цель – повысить эффективность приложения за счёт улучшения взаимодействия с БД, в нашей работе рассматриваются следующие задачи:
• Определить и уметь находить вычислительно неэффективные фрагменты кода;
• На основе статического и динамического анализа выдавать советы по улучшению исходного кода;
• Производить трансформацию (рефакторинг) в автоматическом режиме;
Что касается первой подзадачи, то было решено начать с простых вещей, например, однотипных запросов в цикле, постепенно переходя к анализу более сложных случаев. При решении второй подзадачи под динамическим анализом подразумевается замеры времени выполнения методов и общего времени выполнения приложения, а также построение и простейший анализ «графа вызовов». Третья подзадача является не только самой сложной по реализации, но и самой важной. Для её реализации было решено использовать open-source библиотеку Java
Parser [9], которая переводит исходный код приложения в абстрактное синтаксическое дерево.
Для решения задач, были выбраны следующие технологии: драйвер JDBC и СУБД Oracle 11G. Версия Java не так принципиальна на данном этапе нашего исследования, но использовался JDK версии 1.8.
На основе анализа проблемы для ряда простых шаблонов намеченные задачи были решены. Благодаря open-source инструментам, мы синтаксическое дерево, а также вносить необходимые изменения в него.
Была исследована и реализована возможность выделения предопределённых вычислительно неэффективных фрагментов программного кода,
касающиеся выполнения SQL-запросов в цикле. Исходя из выделенных
«проблемных» шаблонов, мы смогли выдавать советы по улучшению
программного кода (запись в лог-файл). Были приведены и имплементированы алгоритмы по поиску и автоматической трансформации найденных неэффективных фрагментов. Для оценки полезности и эффективности выполненных посредством трансформации изменений мы использовали комплекс из различных оценок, таких как цикломатическая сложность и замеры времени выполнения фрагмента кода (приложения). Для проверки эквивалентности произведённых изменений – использовали JUnit-тесты.
Как показали эксперименты, после произведённых трансформаций ранее наблюдаемый линейный рост времени выполнения «проблемных» фрагментов кода практически сводится к постоянной.
В будущем целесообразно рассмотреть более общие и сложные шаблоны, зависящие от конкретных требований к коду анализируемого приложения.
[1] Cao W., Shasha D. AppSleuth: a tool for database tuning at the
application level // EDBT ’13 Proceedings of the 16th International
Conference on Extending Database Technology. Pages 589–600.
[2] Dombrovskaya H., Lee R. Talking to the Database in a Semantically
Rich Way // Proc. of EDBT/ICDT’17 Joint Conference, March 24-28,
2014, Athens, Greece.
[3] Jeon S.-U., Lee J.-S., Bae D.-H. An Automated Refactoring Approach
to Design Pattern-Based Program Transformations in Java Programs
// APSEC ’02 Proceedings of the Ninth Asia-Pacific Software
Engineering Conference. Pages 337–345.
[4] Moghadam I. H., Ó Cinnéide M. Automated Refactoring Using
Design Differencing // 2012 16th European Conference on Software
Maintenance and Reengineering (CSMR). Pages 43–52.
[5] Christopoulou A., Giakoumakis E. A., Zafeiris E. V., Soukara V.
Automated refactoring to the Strategy design pattern // Journal
Information and Software Technology. Volume 54, Issue 11, November
2012. Pages 1202–1214.
[6] McCabe T. J. A Complexity Measure // IEEE Transactions on
Software Engineering (Volume:SE-2, Issue: 4). Pages 308–320.
[7] Myers J. G. An extension to the cyclomatic measure of program
complexity // ACM SIGPLAN Notices. Volume 12, Issue 10, October
1977. Pages 61–64.
[8] Bowman T.I., Godfrey W. M., Holt C. R. Extracting Source Models
from Java Programs: Parse, Disassemble, or Profile? // The 1999
ACM SIGPLAN Workshop on ProgramAnalysis for Software Tools and
Engineering
32[9] Java Parser with AST generation and visitor support. https://
github.com/javaparser/javaparser
[10] Java Parser Roaster. https://github.com/forge/roaster
[11] Software Complexity Visualizer CyVis. http://cyvis.sourceforge.
net/
[12] Eclipse Metrics plugin. https://sourceforge.net/projects/
metrics/
[13] CheckStyle tool. http://checkstyle.sourceforge.net/
[14] WebGraph http://webgraph.di.unimi.it/