Skip to content

Commit 47a35f0

Browse files
committed
Add container-performance-choice opengrep rule for Chromium
Suggest base::flat_map over std::map for better performance with small datasets, following Chromium performance guidelines.
1 parent 4c1a170 commit 47a35f0

2 files changed

Lines changed: 114 additions & 0 deletions

File tree

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
// Test cases for container-performance-choice rule
2+
#include <map>
3+
#include <set>
4+
#include "base/containers/flat_map.h"
5+
#include "base/containers/flat_set.h"
6+
7+
class TestClass {
8+
public:
9+
void BadExamples() {
10+
// SHOULD TRIGGER: std::map for small/simple usage (consider base::flat_map)
11+
// ruleid: chromium-std-map-performance-consideration
12+
std::map<std::string, int> small_cache;
13+
small_cache["key1"] = 1;
14+
small_cache["key2"] = 2;
15+
16+
// SHOULD TRIGGER: std::set for small collections (consider base::flat_set)
17+
// ruleid: chromium-std-map-performance-consideration
18+
std::set<int> small_ids;
19+
small_ids.insert(1);
20+
small_ids.insert(2);
21+
22+
// SHOULD TRIGGER: std::multimap usage (consider alternatives)
23+
// ruleid: chromium-std-map-performance-consideration
24+
std::multimap<std::string, std::string> headers;
25+
headers.emplace("Content-Type", "text/html");
26+
27+
// SHOULD TRIGGER: std::multiset usage (consider alternatives)
28+
// ruleid: chromium-std-map-performance-consideration
29+
std::multiset<int> duplicate_values;
30+
duplicate_values.insert(1);
31+
duplicate_values.insert(1);
32+
}
33+
34+
void GoodExamples() {
35+
// SHOULD NOT TRIGGER: Using base::flat_map (preferred for small containers)
36+
// ok: chromium-std-map-performance-consideration
37+
base::flat_map<std::string, int> config_map;
38+
config_map["setting1"] = 100;
39+
config_map["setting2"] = 200;
40+
41+
// SHOULD NOT TRIGGER: Using base::flat_set (preferred for small sets)
42+
// ok: chromium-std-map-performance-consideration
43+
base::flat_set<std::string> enabled_features;
44+
enabled_features.insert("feature1");
45+
enabled_features.insert("feature2");
46+
47+
// SHOULD NOT TRIGGER: Other standard containers are fine
48+
// ok: chromium-std-map-performance-consideration
49+
std::vector<int> data = {1, 2, 3, 4, 5};
50+
// ok: chromium-std-map-performance-consideration
51+
std::unordered_map<std::string, int> hash_map;
52+
hash_map["key"] = 42;
53+
}
54+
};
55+
56+
class DatabaseIndex {
57+
private:
58+
// SHOULD TRIGGER: No justification for std::map usage
59+
// ruleid: chromium-std-map-performance-consideration
60+
std::map<std::string, bool> feature_flags_;
61+
62+
// SHOULD NOT TRIGGER: base::flat_map usage (preferred)
63+
// ok: chromium-std-map-performance-consideration
64+
base::flat_map<std::string, int> counters_;
65+
};
66+
67+
// Write-once, read-many scenario
68+
class ConfigReader {
69+
public:
70+
void LoadConfig() {
71+
// SHOULD NOT TRIGGER: base::flat_map ideal for write-once scenario
72+
// ok: chromium-std-map-performance-consideration
73+
base::flat_map<std::string, std::string> settings;
74+
settings["timeout"] = "30";
75+
settings["retries"] = "3";
76+
77+
// SHOULD TRIGGER: std::map not ideal for write-once scenario
78+
// ruleid: chromium-std-map-performance-consideration
79+
std::map<std::string, int> limits;
80+
limits["max_connections"] = 100;
81+
limits["buffer_size"] = 8192;
82+
}
83+
};
84+
85+
struct Record {
86+
int id;
87+
std::string data;
88+
};
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
rules:
2+
- id: chromium-std-map-performance-consideration
3+
metadata:
4+
author: Andrea Brancaleoni <abc@pompel.me>
5+
references:
6+
- https://chromium.googlesource.com/chromium/src/+/main/base/containers/README.md
7+
source: https://github.com/brave/security-action/blob/main/assets/opengrep_rules/client/container-performance-choice.yaml
8+
assignees: |
9+
thypon
10+
cdesouza-chromium
11+
category: correctness
12+
languages: [cpp, c]
13+
message: |
14+
Consider using base::flat_map/base::flat_set instead of std::map/std::set
15+
for small containers or write-once scenarios. Chromium guidelines suggest:
16+
- Use base::flat_map for small collections (< ~100 elements)
17+
- Use base::flat_map for write-once, read-many scenarios
18+
- Only use std::map for large containers with frequent writes
19+
- Use std::map if you need pointer stability
20+
severity: INFO
21+
patterns:
22+
- pattern-either:
23+
- pattern: std::map<$KEY, $VALUE> $VAR;
24+
- pattern: std::set<$TYPE> $VAR;
25+
- pattern: std::multimap<$KEY, $VALUE> $VAR;
26+
- pattern: std::multiset<$TYPE> $VAR;

0 commit comments

Comments
 (0)