Skip to content

Commit ccc8f6c

Browse files
authored
Avoid Unstable Sort (paritytech#12455)
* dont use unstable sort * remove comment * add clippy rule
1 parent 1bf2e6d commit ccc8f6c

File tree

9 files changed

+14
-17
lines changed

9 files changed

+14
-17
lines changed

.cargo/config.toml

+3-2
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,15 @@ rustflags = [
1818
"-Aclippy::borrowed-box", # Reasonable to fix this one
1919
"-Aclippy::too-many-arguments", # (Turning this on would lead to)
2020
"-Aclippy::unnecessary_cast", # Types may change
21-
"-Aclippy::identity-op", # One case where we do 0 +
21+
"-Aclippy::identity-op", # One case where we do 0 +
2222
"-Aclippy::useless_conversion", # Types may change
2323
"-Aclippy::unit_arg", # styalistic.
2424
"-Aclippy::option-map-unit-fn", # styalistic
25-
"-Aclippy::bind_instead_of_map", # styalistic
25+
"-Aclippy::bind_instead_of_map", # styalistic
2626
"-Aclippy::erasing_op", # E.g. 0 * DOLLARS
2727
"-Aclippy::eq_op", # In tests we test equality.
2828
"-Aclippy::while_immutable_condition", # false positives
2929
"-Aclippy::needless_option_as_deref", # false positives
3030
"-Aclippy::derivable_impls", # false positives
31+
"-Aclippy::stable_sort_primitive", # prefer stable sort
3132
]

bin/node/bench/src/core.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ pub fn run_benchmark(benchmark: Box<dyn BenchmarkDescription>, mode: Mode) -> Be
132132
durations.push(duration.as_nanos());
133133
}
134134

135-
durations.sort_unstable();
135+
durations.sort();
136136

137137
let raw_average = (durations.iter().sum::<u128>() / (durations.len() as u128)) as u64;
138138
let average = (durations.iter().skip(10).take(30).sum::<u128>() / 30) as u64;

client/rpc-servers/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ fn format_allowed_hosts(addrs: &[SocketAddr]) -> Vec<String> {
198198

199199
fn build_rpc_api<M: Send + Sync + 'static>(mut rpc_api: RpcModule<M>) -> RpcModule<M> {
200200
let mut available_methods = rpc_api.method_names().collect::<Vec<_>>();
201-
available_methods.sort_unstable();
201+
available_methods.sort();
202202

203203
rpc_api
204204
.register_method("rpc_methods", move |_, _| {

frame/benchmarking/src/analysis.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ impl Analysis {
181181
})
182182
.collect();
183183

184-
values.sort_unstable();
184+
values.sort();
185185
let mid = values.len() / 2;
186186

187187
Some(Self {
@@ -311,7 +311,7 @@ impl Analysis {
311311
}
312312

313313
for (_, rs) in results.iter_mut() {
314-
rs.sort_unstable();
314+
rs.sort();
315315
let ql = rs.len() / 4;
316316
*rs = rs[ql..rs.len() - ql].to_vec();
317317
}

frame/contracts/src/wasm/runtime.rs

+1-5
Original file line numberDiff line numberDiff line change
@@ -1976,11 +1976,7 @@ pub mod env {
19761976
data_len: u32,
19771977
) -> Result<(), TrapReason> {
19781978
fn has_duplicates<T: Ord>(items: &mut Vec<T>) -> bool {
1979-
// # Warning
1980-
//
1981-
// Unstable sorts are non-deterministic across architectures. The usage here is OK
1982-
// because we are rejecting duplicates which removes the non determinism.
1983-
items.sort_unstable();
1979+
items.sort();
19841980
// Find any two consecutive equal elements.
19851981
items.windows(2).any(|w| match &w {
19861982
&[a, b] => a == b,

frame/election-provider-multi-phase/src/mock.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ pub fn trim_helpers() -> TrimHelpers {
155155
seq_phragmen(desired_targets as usize, targets.clone(), voters.clone(), None).unwrap();
156156

157157
// sort by decreasing order of stake
158-
assignments.sort_unstable_by_key(|assignment| {
158+
assignments.sort_by_key(|assignment| {
159159
std::cmp::Reverse(stakes.get(&assignment.who).cloned().unwrap_or_default())
160160
});
161161

frame/examples/basic/src/benchmarking.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ benchmarks! {
6363
}
6464
}: {
6565
// The benchmark execution phase could also be a closure with custom code
66-
m.sort_unstable();
66+
m.sort();
6767
}
6868

6969
// This line generates test cases for benchmarking, and could be run by:

primitives/npos-elections/fuzzer/src/common.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ pub fn generate_random_npos_inputs(
8080
}
8181
candidates.push(id);
8282
}
83-
candidates.sort_unstable();
83+
candidates.sort();
8484
candidates.dedup();
8585
assert_eq!(candidates.len(), candidate_count);
8686

@@ -99,11 +99,11 @@ pub fn generate_random_npos_inputs(
9999

100100
let mut chosen_candidates = Vec::with_capacity(n_candidates_chosen);
101101
chosen_candidates.extend(candidates.choose_multiple(&mut rng, n_candidates_chosen));
102-
chosen_candidates.sort_unstable();
102+
chosen_candidates.sort();
103103
voters.push((id, vote_weight, chosen_candidates));
104104
}
105105

106-
voters.sort_unstable();
106+
voters.sort();
107107
voters.dedup_by_key(|(id, _weight, _chosen_candidates)| *id);
108108
assert_eq!(voters.len(), voter_count);
109109

utils/frame/benchmarking-cli/src/shared/stats.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ impl Stats {
112112
/// Returns the specified percentile for the given data.
113113
/// This is best effort since it ignores the interpolation case.
114114
fn percentile(mut xs: Vec<u64>, p: f64) -> u64 {
115-
xs.sort_unstable();
115+
xs.sort();
116116
let index = (xs.len() as f64 * p).ceil() as usize - 1;
117117
xs[index.clamp(0, xs.len() - 1)]
118118
}

0 commit comments

Comments
 (0)