Improved note-on performance

- Compute the hash value on ModKey construction and memorize it
- Fix missing region ID in the hash value of ModKey
This commit is contained in:
KIRA Ryouta 2024-02-03 18:30:31 +01:00 committed by Paul Ferrand
parent 3d7bcb4968
commit f8fc628b3e
4 changed files with 44 additions and 9 deletions

View file

@ -228,7 +228,7 @@ std::string ModKey::toString() const
}
}
ModKey ModKey::getSourceDepthKey(ModKey source, ModKey target)
ModKey ModKey::getSourceDepthKey(const ModKey& source, const ModKey& target)
{
const NumericId<Region> region = source.region();
const ModKey::Parameters& tp = target.parameters();

View file

@ -26,7 +26,10 @@ public:
ModKey() = default;
explicit ModKey(ModId id, NumericId<Region> region = {}, Parameters params = {})
: id_(id), region_(region), params_(params), flags_(ModIds::flags(id_)) {}
: id_(id), region_(region), params_(params), flags_(ModIds::flags(id_))
{
calculateHash();
}
static ModKey createCC(uint16_t cc, uint8_t curve, uint16_t smooth, float step);
static ModKey createNXYZ(ModId id, NumericId<Region> region = {}, uint8_t N = 0, uint8_t X = 0, uint8_t Y = 0, uint8_t Z = 0);
@ -46,7 +49,7 @@ public:
* @brief Obtain the modulation key of the source depth, in the connection
* between source and target, if such a key exists.
*/
static ModKey getSourceDepthKey(ModKey source, ModKey target);
static ModKey getSourceDepthKey(const ModKey& source, const ModKey& target);
struct RawParameters {
union {
@ -94,6 +97,10 @@ public:
return !this->operator==(other);
}
public:
size_t hash() const { return hash_; };
private:
void calculateHash();
private:
//! Identifier
@ -104,6 +111,9 @@ private:
Parameters params_ {};
// Memorize the flag
int flags_;
// Hash number
size_t hash_ = size_t(16806506973555142816ULL);
};
} // namespace sfz

View file

@ -10,12 +10,27 @@
#include "utility/StringViewHelpers.h"
#include <cstdint>
size_t std::hash<sfz::ModKey>::operator()(const sfz::ModKey &key) const
void sfz::ModKey::calculateHash()
{
uint64_t k = hashNumber(static_cast<int>(key.id()));
const sfz::ModKey::Parameters& p = key.parameters();
#if !defined(NDEBUG)
static bool once = false;
if (!once) {
once = true;
ModKey m;
size_t h = m.hash();
m.calculateHash();
if (h != m.hash()) {
printf("ModKey default hash is %llu\n", (uint64_t)m.hash());
assert(false && "Number of variables is wrong. Needs updating the default hash.");
}
}
#endif
switch (key.id()) {
uint64_t k = hashNumber(static_cast<int>(id()));
k = hashNumber(region_.number(), k);
const sfz::ModKey::Parameters& p = parameters();
switch (id()) {
case sfz::ModId::Controller:
k = hashNumber(p.cc, k);
k = hashNumber(p.curve, k);
@ -29,5 +44,10 @@ size_t std::hash<sfz::ModKey>::operator()(const sfz::ModKey &key) const
k = hashNumber(p.Z, k);
break;
}
return k;
hash_ = size_t(k);
}
size_t std::hash<sfz::ModKey>::operator()(const sfz::ModKey &key) const
{
return key.hash();
}

View file

@ -101,7 +101,12 @@ uint64_t hashNumber(Int i, uint64_t h = Fnv1aBasis)
{
static_assert(std::is_arithmetic<Int>::value,
"The hashed object must be of arithmetic type");
return hash(absl::string_view(reinterpret_cast<const char*>(&i), sizeof(i)), h);
union {
uint64_t u64;
Int i;
} un {};
un.i = i;
return (h ^ un.u64) * Fnv1aPrime;
}
/**