Add some performance profiling, increase performance for loading thumbnail data

This commit is contained in:
2025-07-19 10:44:51 +02:00
parent 1077491423
commit 5cff2cdc86
5 changed files with 84 additions and 12 deletions

View File

@ -67,8 +67,7 @@ type Migration = {
name: string;
statement: string;
};
const db: sqlite3.Database = new sqlite3.Database('moshingmammut.db');
const db: sqlite3.Database = new sqlite3.cached.Database('moshingmammut.db');
export function close() {
try {
@ -660,12 +659,15 @@ function getSongThumbnailData(
thumbUrls: string[]
): Promise<Map<string, SongThumbnailImage[]>> {
return new Promise((resolve, reject) => {
const start = performance.now();
db.all(
`SELECT song_thumbnailUrl, file, sizeDescriptor, kind
FROM songsthumbnails
WHERE song_thumbnailUrl IN (${thumbUrlsParams});`,
thumbUrls,
(err, rows: SongThumbnailAvatarRow[]) => {
const afterQuery = performance.now();
logger.verbose('thumbnail query took', afterQuery - start, 'ms');
if (err != null) {
logger.error('Error loading avatars', err);
reject(err);
@ -687,6 +689,8 @@ function getSongThumbnailData(
},
new Map()
);
const afterReduce = performance.now();
logger.verbose('thumbnail reduce took', afterReduce - afterQuery, 'ms');
resolve(thumbnailMap);
}
);
@ -730,10 +734,16 @@ export async function getPosts(
before: string | null,
limit: number
): Promise<Post[]> {
const start = performance.now();
if (!databaseReady) {
await waitReady();
}
return await getPostsInternal(since, before, limit);
const ready = performance.now();
logger.debug('DB ready took', ready - start, 'ms');
const posts = await getPostsInternal(since, before, limit);
const afterPosts = performance.now();
logger.debug('DB posts', afterPosts - ready, 'ms');
return posts;
}
async function getPostsInternal(
@ -741,6 +751,7 @@ async function getPostsInternal(
before: string | null,
limit: number
): Promise<Post[]> {
const start = performance.now();
let filterQuery = '';
const params: FilterParameter = { $limit: limit };
if (since === null && before === null) {
@ -763,8 +774,12 @@ async function getPostsInternal(
params[acctParam] = ignoredUser;
params[usernameParam] = ignoredUser;
});
const afterFilter = performance.now();
logger.debug('filterQuery took', afterFilter - start, 'ms');
const rows = await getPostData(filterQuery, params);
const afterRows = performance.now();
logger.debug('rows took', afterRows - afterFilter, 'ms');
if (rows.length === 0) {
// No need to check for tags and songs
return [];
@ -772,19 +787,45 @@ async function getPostsInternal(
const postIdsParams = rows.map(() => '?').join(', ');
const postIds = rows.map((r: PostRow) => r.url);
const afterParams = performance.now();
logger.debug('params took', afterParams - afterRows, 'ms');
const tagMap = await getTagData(postIdsParams, postIds);
const afterTag = performance.now();
logger.debug('rows took', afterTag - afterRows, 'ms');
const songMap = await getSongData(postIdsParams, postIds);
for (const entry of songMap) {
for (const songInfo of entry[1]) {
const thumbs = await getSongThumbnails(songInfo);
songInfo.resizedThumbnails = thumbs;
const afterSong = performance.now();
logger.debug('rows took', afterSong - afterTag, 'ms');
const turls = songMap
.values()
.flatMap((x) => x)
.map((x) => x.thumbnailUrl)
.filter((x) => x !== undefined)
.toArray();
if (turls) {
const tMap = await getSongThumbnailData('?, '.repeat(turls.length).slice(0, -2), turls);
for (const entry of songMap) {
for (const songInfo of entry[1]) {
if (songInfo.thumbnailUrl === undefined) {
continue;
}
const thumbs = tMap.get(songInfo.thumbnailUrl) ?? [];
songInfo.resizedThumbnails = thumbs;
}
}
}
const afterThumbs2 = performance.now();
logger.debug('thumbs took', afterThumbs2 - afterSong, 'ms');
const accountUrls = [...new Set(rows.map((r: PostRow) => r.account_url))];
const accountUrlsParams = accountUrls.map(() => '?').join(', ');
const avatars = await getAvatarData(accountUrlsParams, accountUrls);
const afterAvatar = performance.now();
logger.debug('avatar took', afterAvatar - afterThumbs2, 'ms');
const posts = rows.map((row) => {
return {
id: row.id,
@ -804,6 +845,8 @@ async function getPostsInternal(
songs: songMap.get(row.url) || []
} as Post;
});
const afterMap = performance.now();
logger.debug('map took', afterMap - afterAvatar, 'ms');
return posts;
}