mirror of
https://github.com/webmproject/libwebp.git
synced 2024-12-28 14:38:21 +01:00
CostManager: cache one interval and re-use it when possible
In a lot of cases, only one interval is used. This can cause a lot of malloc/free cycles for only 56 bytes. By caching this single interval and re-using it, we remove this cycle in most frequent cases. Change-Id: Ia22d583f60ae438c216612062316b20ecb34f029
This commit is contained in:
parent
41b7e6b56e
commit
0481d42ad8
@ -619,6 +619,8 @@ typedef struct {
|
|||||||
double cost_cache_[MAX_LENGTH]; // Contains the GetLengthCost(cost_model, k).
|
double cost_cache_[MAX_LENGTH]; // Contains the GetLengthCost(cost_model, k).
|
||||||
float* costs_;
|
float* costs_;
|
||||||
uint16_t* dist_array_;
|
uint16_t* dist_array_;
|
||||||
|
CostInterval spare_; // most of the time, we only will be using a single
|
||||||
|
int spare_used_; // interval. => We re-use this one first if possible.
|
||||||
} CostManager;
|
} CostManager;
|
||||||
|
|
||||||
static int IsCostCacheIntervalWritable(int start, int end) {
|
static int IsCostCacheIntervalWritable(int start, int end) {
|
||||||
@ -642,7 +644,11 @@ static void CostManagerClear(CostManager* const manager) {
|
|||||||
CostInterval* interval = manager->head_;
|
CostInterval* interval = manager->head_;
|
||||||
while (interval != NULL) {
|
while (interval != NULL) {
|
||||||
CostInterval* const next = interval->next_;
|
CostInterval* const next = interval->next_;
|
||||||
WebPSafeFree(interval);
|
if (manager->spare_used_ && interval == &manager->spare_) {
|
||||||
|
manager->spare_used_ = 0;
|
||||||
|
} else {
|
||||||
|
WebPSafeFree(interval);
|
||||||
|
}
|
||||||
interval = next;
|
interval = next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -663,6 +669,7 @@ static int CostManagerInit(CostManager* const manager,
|
|||||||
manager->head_ = NULL;
|
manager->head_ = NULL;
|
||||||
manager->count_ = 0;
|
manager->count_ = 0;
|
||||||
manager->dist_array_ = dist_array;
|
manager->dist_array_ = dist_array;
|
||||||
|
manager->spare_used_ = 0;
|
||||||
|
|
||||||
// Fill in the cost_cache_.
|
// Fill in the cost_cache_.
|
||||||
manager->cache_intervals_size_ = 1;
|
manager->cache_intervals_size_ = 1;
|
||||||
@ -793,8 +800,11 @@ static WEBP_INLINE void PopInterval(CostManager* const manager,
|
|||||||
if (interval == NULL) return;
|
if (interval == NULL) return;
|
||||||
|
|
||||||
ConnectIntervals(manager, interval->previous_, next);
|
ConnectIntervals(manager, interval->previous_, next);
|
||||||
|
if (interval == &manager->spare_) {
|
||||||
WebPSafeFree(interval);
|
manager->spare_used_ = 0;
|
||||||
|
} else {
|
||||||
|
WebPSafeFree(interval);
|
||||||
|
}
|
||||||
--manager->count_;
|
--manager->count_;
|
||||||
assert(manager->count_ >= 0);
|
assert(manager->count_ >= 0);
|
||||||
}
|
}
|
||||||
@ -857,12 +867,16 @@ static WEBP_INLINE void InsertInterval(CostManager* const manager,
|
|||||||
UpdateCostPerInterval(manager, start, end, index, distance_cost);
|
UpdateCostPerInterval(manager, start, end, index, distance_cost);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (!manager->spare_used_) {
|
||||||
interval_new = (CostInterval*)WebPSafeMalloc(1, sizeof(*interval_new));
|
interval_new = &manager->spare_;
|
||||||
if (interval_new == NULL) {
|
manager->spare_used_ = 1;
|
||||||
// Write down the interval if we cannot create it.
|
} else {
|
||||||
UpdateCostPerInterval(manager, start, end, index, distance_cost);
|
interval_new = (CostInterval*)WebPSafeMalloc(1, sizeof(*interval_new));
|
||||||
return;
|
if (interval_new == NULL) {
|
||||||
|
// Write down the interval if we cannot create it.
|
||||||
|
UpdateCostPerInterval(manager, start, end, index, distance_cost);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interval_new->distance_cost_ = distance_cost;
|
interval_new->distance_cost_ = distance_cost;
|
||||||
|
Loading…
Reference in New Issue
Block a user