Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2e39691d authored by Jorrit Jongma's avatar Jorrit Jongma Committed by Chirayu Desai
Browse files

Add simple caching to XML compilation



XML compilation stage will perform many (expensive) resource ID
lookups - for the same entries. Adding this simple cache can
dramatically improve performance of this stage (often a bottleneck)

Updated: fixed for Mac OS X (also tested on Windows, Linux)

Change-Id: Ib1ab82ba9bf901bc2a3f9027b47d680861d6c315
Signed-off-by: default avatarJorrit Jongma <jorrit@jongma.org>
parent 77a16ec6
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ LOCAL_SRC_FILES := \
	StringPool.cpp \
	XMLNode.cpp \
	ResourceFilter.cpp \
	ResourceIdCache.cpp \
	ResourceTable.cpp \
	Images.cpp \
	Resource.cpp \
+67 −0
Original line number Diff line number Diff line
//
// Copyright 2012 The Android Open Source Project
//
// Cache for resIds - we tend to lookup the same thing repeatedly
//

#include "ResourceIdCache.h"

struct lutEntry {
    String16 package;
    String16 type;
    String16 name;
    bool onlyPublic;
    uint32_t resId;
};

// more than enough - wastes about 100kb of memory (ex strings)
static const int lutCapacity = 4096;
static struct lutEntry* lut = NULL;
static int lutUsed = 0;

static bool lutAlloc() {
    if (lut == NULL) lut = new struct lutEntry[lutCapacity];
    return (lut != NULL);
}

uint32_t ResourceIdCache::lookup(const String16& package,
                                 const String16& type,
                                 const String16& name,
                                 bool onlyPublic)
{
    if (!lutAlloc()) return 0;

    for (int i = 0; i < lutUsed; i++) {
        if (
            // name is most likely to be different
            (name == lut[i].name) &&
            (type == lut[i].type) &&
            (package == lut[i].package) &&
            (onlyPublic == lut[i].onlyPublic)
        ) {
            return lut[i].resId;
        }
    }
    return 0;
}

bool ResourceIdCache::store(const String16& package,
                            const String16& type,
                            const String16& name,
                            bool onlyPublic,
                            uint32_t resId)
{
    if (!lutAlloc()) return false;

    if (lutUsed < lutCapacity) {
        lut[lutUsed].package = String16(package);
        lut[lutUsed].type = String16(type);
        lut[lutUsed].name = String16(name);
        lut[lutUsed].onlyPublic = onlyPublic;
        lut[lutUsed].resId = resId;
        lutUsed++;
        return true;
    } else {
        return false;
    }
}
+26 −0
Original line number Diff line number Diff line
//
// Copyright 2012 The Android Open Source Project
//
// Cache for resIds - we tend to lookup the same thing repeatedly
//

#ifndef RESOURCE_ID_CACHE_H
#define RESOURCE_ID_CACHE_H

#include "StringPool.h"

class ResourceIdCache {
public:
    static uint32_t lookup(const String16& package,
                           const String16& type,
                           const String16& name,
                           bool onlyPublic);

    static bool store(const String16& package,
                      const String16& type,
                      const String16& name,
                      bool onlyPublic,
                      uint32_t resId);
};

#endif
+6 −1
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@

#include "XMLNode.h"
#include "ResourceFilter.h"
#include "ResourceIdCache.h"

#include <androidfw/ResourceTypes.h>
#include <utils/ByteOrder.h>
@@ -2057,7 +2058,11 @@ uint32_t ResourceTable::getResId(const String16& ref,
                     String8(name).string()));
        return 0;
    }
    uint32_t res = getResId(package, type, name, onlyPublic && refOnlyPublic);
    uint32_t res = ResourceIdCache::lookup(package, type, name, onlyPublic && refOnlyPublic);
    if (res == 0) {
        res = getResId(package, type, name, onlyPublic && refOnlyPublic);
        ResourceIdCache::store(package, type, name, onlyPublic && refOnlyPublic, res);
    }
    NOISY(printf("Expanded resource: p=%s, t=%s, n=%s, res=%d\n",
                 String8(package).string(), String8(type).string(),
                 String8(name).string(), res));