qemu*xml2*test: Cache capabilities between tests

Invoking the XML parser every time is quite expensive. Since we have a
deep copy function for 'virQEMUCapsPtr' object, we can cache the parsed
results lazily.

This brings significant speedup to qemuxml2argvtest:

real	0m2.234s
user	0m2.140s
sys	0m0.089s

vs.

real	0m1.161s
user	0m1.087s
sys	0m0.072s

qemuxml2xmltest benefits too:

real	0m0.879s
user	0m0.801s
sys	0m0.071s

vs.

real	0m0.466s
user	0m0.424s
sys	0m0.040s

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Jonathon Jongsma <jjongsma@redhat.com>
This commit is contained in:
Peter Krempa 2021-02-19 16:46:45 +01:00
parent 564f46e3c5
commit 4865dd673d
5 changed files with 22 additions and 6 deletions

View File

@ -73,6 +73,7 @@ mymain(void)
g_autofree char *fakerootdir = NULL;
g_autoptr(virQEMUDriverConfig) cfg = NULL;
g_autoptr(GHashTable) capslatest = NULL;
g_autoptr(GHashTable) capscache = virHashNew(virObjectFreeHashData);
g_autoptr(virConnect) conn = NULL;
capslatest = testQemuGetLatestCaps();
@ -109,7 +110,7 @@ mymain(void)
static struct testQemuInfo info = { \
.name = _name, \
}; \
if (testQemuInfoSetArgs(&info, capslatest, \
if (testQemuInfoSetArgs(&info, capscache, capslatest, \
ARG_QEMU_CAPS, QEMU_CAPS_LAST, \
ARG_END) < 0 || \
qemuTestCapsCacheInsert(driver.qemuCapsCache, info.qemuCaps) < 0) { \

View File

@ -789,6 +789,7 @@ mymain(void)
g_autofree char *fakerootdir = NULL;
g_autoptr(GHashTable) capslatest = NULL;
g_autoptr(GHashTable) qapiSchemaCache = virHashNew((GDestroyNotify) virHashFree);
g_autoptr(GHashTable) capscache = virHashNew(virObjectFreeHashData);
fakerootdir = g_strdup(FAKEROOTDIRTEMPLATE);
@ -883,7 +884,7 @@ mymain(void)
.name = _name, \
}; \
info.qapiSchemaCache = qapiSchemaCache; \
if (testQemuInfoSetArgs(&info, capslatest, \
if (testQemuInfoSetArgs(&info, capscache, capslatest, \
__VA_ARGS__, ARG_END) < 0) \
return EXIT_FAILURE; \
testInfoSetPaths(&info, _suffix); \

View File

@ -85,6 +85,7 @@ mymain(void)
g_autofree char *fakerootdir = NULL;
g_autoptr(virQEMUDriverConfig) cfg = NULL;
g_autoptr(GHashTable) capslatest = NULL;
g_autoptr(GHashTable) capscache = virHashNew(virObjectFreeHashData);
g_autoptr(virConnect) conn = NULL;
capslatest = testQemuGetLatestCaps();
@ -130,7 +131,7 @@ mymain(void)
static struct testQemuInfo info = { \
.name = _name, \
}; \
if (testQemuInfoSetArgs(&info, capslatest, \
if (testQemuInfoSetArgs(&info, capscache, capslatest, \
__VA_ARGS__, \
ARG_END) < 0 || \
qemuTestCapsCacheInsert(driver.qemuCapsCache, info.qemuCaps) < 0) { \

View File

@ -681,6 +681,7 @@ testQemuCapsIterate(const char *suffix,
int
testQemuInfoSetArgs(struct testQemuInfo *info,
GHashTable *capscache,
GHashTable *capslatest, ...)
{
va_list argptr;
@ -773,6 +774,7 @@ testQemuInfoSetArgs(struct testQemuInfo *info,
if (!qemuCaps && capsarch && capsver) {
bool stripmachinealiases = false;
virQEMUCapsPtr cachedcaps = NULL;
info->arch = virArchFromString(capsarch);
@ -784,11 +786,21 @@ testQemuInfoSetArgs(struct testQemuInfo *info,
TEST_QEMU_CAPS_PATH, capsver, capsarch);
}
if (!(qemuCaps = qemuTestParseCapabilitiesArch(info->arch, capsfile)))
if (!g_hash_table_lookup_extended(capscache, capsfile, NULL, (void **) &cachedcaps)) {
if (!(qemuCaps = qemuTestParseCapabilitiesArch(info->arch, capsfile)))
goto cleanup;
if (stripmachinealiases)
virQEMUCapsStripMachineAliases(qemuCaps);
cachedcaps = qemuCaps;
g_hash_table_insert(capscache, g_strdup(capsfile), g_steal_pointer(&qemuCaps));
}
if (!(qemuCaps = virQEMUCapsNewCopy(cachedcaps)))
goto cleanup;
if (stripmachinealiases)
virQEMUCapsStripMachineAliases(qemuCaps);
info->flags |= FLAG_REAL_CAPS;
/* provide path to the replies file for schema testing */

View File

@ -110,6 +110,7 @@ int testQemuCapsIterate(const char *suffix,
void *opaque);
int testQemuInfoSetArgs(struct testQemuInfo *info,
GHashTable *capscache,
GHashTable *capslatest, ...);
void testQemuInfoClear(struct testQemuInfo *info);