Я создаю REST API для расписаний занятий в колледже, и вставка данных в базу данных занимает целую вечность. Моя программа работает, загружая расписание в формате PDF с веб-сайта моего университета, удаляя его текст и распечатывая его в текстовый файл, а затем анализируя текстовый файл на предмет подробностей курса. Все полностью функционально, но неэффективно.
После того как сведения о курсе найдены, объект Course создается из класса модели rest и сохраняется в списке.
public class Parser {
private static List<Course> courses;
public static void parse(File file) {
[collecting data...]
Course course = new Course(crn, subject, number, title, department, hours, instructor, size, seats, semester, term);
courses.add(course);
}
public static List<Course> getCourses() {
return courses;
}
}
Как только все курсы найдены, вызывается этот метод для помещения их в базу данных. Загрузка 15 000 курсов занимает ~3 минуты.
/** Constructs a JSON request body and posts course data to the server. */
public static void saveCourses(List<Course> courses) throws URISyntaxException, IOException, InterruptedException {
for (int i = 0; i < courses.size(); i++) {
Gson gson = new Gson();
String json = gson.toJson(courses.get(i));
HttpClient httpClient = HttpClient.newHttpClient();
HttpRequest httpRequest = HttpRequest.newBuilder()
.uri(new URI("http://localhost:8080/course/save"))
.header("Content-Type", "application/json")
.POST(BodyPublishers.ofString(json))
.build();
httpClient.send(httpRequest, BodyHandlers.ofString());
}
}
Я не уверен, что так долго занимает звонок toJson()
или сам запрос, но что я могу сделать, чтобы моя программа работала быстрее?
3 минуты на 15 000 запросов, это около 12 мс на запрос. Это не так уж плохо.
Нет необходимости создавать HttpClient внутри цикла.
Почему 3 минуты — это проблема? Разве это не случается один раз?
Вы ограничены звонками 1:1? Можете ли вы добавить массовый API, получающий список объектов JSON? Можете ли вы отправлять дем-запросы одновременно?
Да. Подводя итог, проблема не столько в том, что обработка на сервере неэффективна, сколько в том, что вы делаете много запросов. Я вижу два подхода к решению этой проблемы:
Course
вместо одного и отправки всего списка одним запросом или, опять же, пакетами. В последнем случае можно попробовать оптимизировать дальше, используя асинхронные запросы.
Начните с профилировщика, чтобы найти узкое место. Это может быть что угодно: от базы данных до медленного подключения к Интернету. Но первое, что нужно сделать, это вывести gson из цикла: в настоящее время вы создаете и собираете мусор 15 000 экземпляров gson, хотя вам следует использовать только 1.