Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@
- Dev: Balance IPv4 and IPv6 connection attempts. (#6804)
- Dev: Factored out recent messages benchmark helper. (#6815)
- Dev: Added `CHATTERINO_FORCE_LTO` CMake option to skip LTO check. (#6816)
- Dev: Added more tests and benchmarks for filters. (#6814)

## 2.5.4

Expand Down
1 change: 1 addition & 0 deletions benchmarks/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ set(benchmark_SOURCES
src/LinkParser.cpp
src/RecentMessages.cpp
src/MessageBuilding.cpp
src/Filters.cpp
# Add your new file above this line!
)

Expand Down
131 changes: 131 additions & 0 deletions benchmarks/src/Filters.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
// SPDX-FileCopyrightText: 2026 Contributors to Chatterino <https://chatterino.com>
//
// SPDX-License-Identifier: MIT

#include "common/Literals.hpp"
#include "controllers/filters/FilterSet.hpp"
#include "MessageBuilding.hpp"
#include "providers/recentmessages/Impl.hpp"

#include <benchmark/benchmark.h>
#include <QFile>
#include <QJsonArray>
#include <QJsonDocument>
#include <QString>

using namespace chatterino;
using namespace Qt::Literals;

namespace {

class FilterMessages : public bench::MessageBenchmark
{
public:
explicit FilterMessages(QString name, QStringList filters)
: bench::MessageBenchmark(std::move(name))
, filterTexts(std::move(filters))
{
}

void run(benchmark::State &state) override
{
auto parsed = recentmessages::detail::parseRecentMessages(
this->messages.object());
auto built = recentmessages::detail::buildRecentMessages(
parsed, this->chan.get());

QList<QUuid> filters;
for (qsizetype i = 0; i < this->filterTexts.size(); i++)
{
// ensure deterministic order
auto id = QUuid(static_cast<uint>(i), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
auto filter = std::make_shared<FilterRecord>(
QString::number(i), this->filterTexts.at(i), id);
if (!filter->valid())
{
qCDebug(chatterinoApp) << i << this->filterTexts[i];
assert(false);
continue;
}
getSettings()->filterRecords.append(filter);
filters.append(id);
}
assert(filters.size() == this->filterTexts.size());
FilterSet set(filters);
assert(set.filterIds().size() == filters.size());

for (auto _ : state)
{
for (const auto &msg : built)
{
bool filtered = set.filter(msg, this->chan);
benchmark::DoNotOptimize(filtered);
benchmark::ClobberMemory();
}
}
}

private:
QStringList filterTexts;
};

void BM_FilterMessages(benchmark::State &state, QString channel,
QStringList filters)
{
FilterMessages bench(std::move(channel), std::move(filters));
bench.run(state);
}

} // namespace

BENCHMARK_CAPTURE(
BM_FilterMessages, nymn_modmessages, u"nymn"_s,
{
uR".(channel.name == "nymn" && author.badges contains "moderator")."_s,
});

BENCHMARK_CAPTURE(
BM_FilterMessages, nymn_mod_party, u"nymn"_s,
{
uR".((author.badges contains "moderator") && (message.content contains "forsenParty"))."_s,
});

BENCHMARK_CAPTURE(BM_FilterMessages, nymn_len40_or_sub, u"nymn"_s,
{
uR".(message.length < 40 || author.subbed)."_s,
});

BENCHMARK_CAPTURE(BM_FilterMessages, nymn_no_sub, u"nymn"_s,
{
uR".(!flags.sub_message)."_s,
});

BENCHMARK_CAPTURE(BM_FilterMessages, nymn_with_color, u"nymn"_s,
{
uR".(!author.no_color)."_s,
});

BENCHMARK_CAPTURE(
BM_FilterMessages, nymn_complex_regex, u"nymn"_s,
{
uR".((message.content match r"^(?!.*(?:my|complex|(re.*x))).*$"))."_s,
});

BENCHMARK_CAPTURE(
BM_FilterMessages, nymn_big_or, u"nymn"_s,
{
uR".((author.subbed && author.sub_length >= 6) || flags.system_message || flags.first_message || flags.automod || flags.sub_message)."_s,
});

BENCHMARK_CAPTURE(
BM_FilterMessages, nymn_with_color_and_edm_single, u"nymn"_s,
{
uR".(!author.no_color && message.content contains "EDM")."_s,
});

BENCHMARK_CAPTURE(BM_FilterMessages, nymn_with_color_and_edm_separate,
u"nymn"_s,
{
uR".(!author.no_color)."_s,
uR".(message.content contains "EDM")."_s,
});
1 change: 1 addition & 0 deletions benchmarks/src/MessageBuilding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ namespace chatterino::bench {
MockMessageApplication::MockMessageApplication()
: highlights(this->settings, &this->accounts)
{
this->settings.disableSave();
}

MessageBenchmark::MessageBenchmark(QString name)
Expand Down
Loading
Loading