Skip to content

Commit f798d5a

Browse files
Faster minmax by using fold
Do less comparisons by considering pairs is smart but this was done by `loop { it.next(), it.next() }` while `it.fold` is generally faster. This results in a lot of changes but most of it is merely moving code and indentation corrections.
1 parent 3067893 commit f798d5a

1 file changed

Lines changed: 33 additions & 36 deletions

File tree

src/minmax.rs

Lines changed: 33 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -67,48 +67,45 @@ where
6767
},
6868
};
6969

70-
loop {
71-
// `first` and `second` are the two next elements we want to look
72-
// at. We first compare `first` and `second` (#1). The smaller one
73-
// is then compared to current minimum (#2). The larger one is
74-
// compared to current maximum (#3). This way we do 3 comparisons
75-
// for 2 elements.
76-
let first = match it.next() {
77-
None => break,
78-
Some(x) => x,
79-
};
80-
let second = match it.next() {
81-
None => {
82-
let first_key = key_for(&first);
70+
let remaining = it.fold(None, |acc, second| match acc {
71+
None => Some(second),
72+
Some(first) => {
73+
// `first` and `second` are the two next elements we want to look
74+
// at. We first compare `first` and `second` (#1). The smaller one
75+
// is then compared to current minimum (#2). The larger one is
76+
// compared to current maximum (#3). This way we do 3 comparisons
77+
// for 2 elements.
78+
let first_key = key_for(&first);
79+
let second_key = key_for(&second);
80+
if !lt(&second, &first, &second_key, &first_key) {
8381
if lt(&first, &min, &first_key, &min_key) {
8482
min = first;
85-
} else if !lt(&first, &max, &first_key, &max_key) {
83+
min_key = first_key;
84+
}
85+
if !lt(&second, &max, &second_key, &max_key) {
86+
max = second;
87+
max_key = second_key;
88+
}
89+
} else {
90+
if lt(&second, &min, &second_key, &min_key) {
91+
min = second;
92+
min_key = second_key;
93+
}
94+
if !lt(&first, &max, &first_key, &max_key) {
8695
max = first;
96+
max_key = first_key;
8797
}
88-
break;
8998
}
90-
Some(x) => x,
91-
};
99+
None
100+
}
101+
});
102+
103+
if let Some(first) = remaining {
92104
let first_key = key_for(&first);
93-
let second_key = key_for(&second);
94-
if !lt(&second, &first, &second_key, &first_key) {
95-
if lt(&first, &min, &first_key, &min_key) {
96-
min = first;
97-
min_key = first_key;
98-
}
99-
if !lt(&second, &max, &second_key, &max_key) {
100-
max = second;
101-
max_key = second_key;
102-
}
103-
} else {
104-
if lt(&second, &min, &second_key, &min_key) {
105-
min = second;
106-
min_key = second_key;
107-
}
108-
if !lt(&first, &max, &first_key, &max_key) {
109-
max = first;
110-
max_key = first_key;
111-
}
105+
if lt(&first, &min, &first_key, &min_key) {
106+
min = first;
107+
} else if !lt(&first, &max, &first_key, &max_key) {
108+
max = first;
112109
}
113110
}
114111

0 commit comments

Comments
 (0)