mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-25 15:33:44 +03:00
Use a HashMap instead of a BTreeMap in Scheduler's internals. Doesn't
affect determistic simulation, but yields a crazy speedup. #54 - 8 hours of downtown: 122s to 102s!!! - prebake: 181s to 160s
This commit is contained in:
parent
82827bd60b
commit
87d233299a
@ -1,6 +1,7 @@
|
|||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::{cmp, ops};
|
use std::{cmp, ops};
|
||||||
|
|
||||||
|
use ordered_float::NotNan;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{trim_f64, Duration};
|
use crate::{trim_f64, Duration};
|
||||||
@ -17,6 +18,12 @@ impl Ord for Time {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl std::hash::Hash for Time {
|
||||||
|
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||||
|
NotNan::new(self.0).unwrap().hash(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Time {
|
impl Time {
|
||||||
pub const START_OF_DAY: Time = Time(0.0);
|
pub const START_OF_DAY: Time = Time(0.0);
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ pub struct PandemicModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// You can schedule callbacks in the future by doing scheduler.push(future time, one of these)
|
// You can schedule callbacks in the future by doing scheduler.push(future time, one of these)
|
||||||
#[derive(Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Clone, Debug)]
|
#[derive(Serialize, Deserialize, PartialEq, Eq, Hash, PartialOrd, Ord, Clone, Debug)]
|
||||||
pub enum Cmd {
|
pub enum Cmd {
|
||||||
BecomeHospitalized(PersonID),
|
BecomeHospitalized(PersonID),
|
||||||
BecomeQuarantined(PersonID),
|
BecomeQuarantined(PersonID),
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::collections::btree_map::Entry;
|
use std::collections::hash_map::Entry;
|
||||||
use std::collections::{BTreeMap, BinaryHeap};
|
use std::collections::{BinaryHeap, HashMap};
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
@ -38,7 +38,7 @@ impl Command {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_type(&self) -> CommandType {
|
fn to_type(&self) -> CommandType {
|
||||||
match self {
|
match self {
|
||||||
Command::SpawnCar(ref create, _) => CommandType::Car(create.vehicle.id),
|
Command::SpawnCar(ref create, _) => CommandType::Car(create.vehicle.id),
|
||||||
Command::SpawnPed(ref create) => CommandType::Ped(create.id),
|
Command::SpawnPed(ref create) => CommandType::Ped(create.id),
|
||||||
@ -57,8 +57,8 @@ impl Command {
|
|||||||
|
|
||||||
/// A smaller version of Command that satisfies many more properties. Only one Command per
|
/// A smaller version of Command that satisfies many more properties. Only one Command per
|
||||||
/// CommandType may exist at a time.
|
/// CommandType may exist at a time.
|
||||||
#[derive(Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Clone, Debug)]
|
#[derive(Serialize, Deserialize, PartialEq, Eq, Hash, PartialOrd, Ord, Clone, Debug)]
|
||||||
pub enum CommandType {
|
enum CommandType {
|
||||||
StartTrip(TripID),
|
StartTrip(TripID),
|
||||||
Car(CarID),
|
Car(CarID),
|
||||||
CarLaggyHead(CarID),
|
CarLaggyHead(CarID),
|
||||||
@ -100,7 +100,7 @@ impl Ord for Item {
|
|||||||
#[derive(Clone, Serialize, Deserialize)]
|
#[derive(Clone, Serialize, Deserialize)]
|
||||||
pub struct Scheduler {
|
pub struct Scheduler {
|
||||||
items: BinaryHeap<Item>,
|
items: BinaryHeap<Item>,
|
||||||
queued_commands: BTreeMap<CommandType, (Command, Time)>,
|
queued_commands: HashMap<CommandType, (Command, Time)>,
|
||||||
|
|
||||||
latest_time: Time,
|
latest_time: Time,
|
||||||
last_time: Time,
|
last_time: Time,
|
||||||
@ -112,7 +112,7 @@ impl Scheduler {
|
|||||||
pub fn new() -> Scheduler {
|
pub fn new() -> Scheduler {
|
||||||
Scheduler {
|
Scheduler {
|
||||||
items: BinaryHeap::new(),
|
items: BinaryHeap::new(),
|
||||||
queued_commands: BTreeMap::new(),
|
queued_commands: HashMap::new(),
|
||||||
latest_time: Time::START_OF_DAY,
|
latest_time: Time::START_OF_DAY,
|
||||||
last_time: Time::START_OF_DAY,
|
last_time: Time::START_OF_DAY,
|
||||||
delta_times: Histogram::new(),
|
delta_times: Histogram::new(),
|
||||||
@ -174,17 +174,6 @@ impl Scheduler {
|
|||||||
self.queued_commands.remove(&cmd.to_type());
|
self.queued_commands.remove(&cmd.to_type());
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO Should panic if a command of this type isn't scheduled. But currently failing
|
|
||||||
// unexpectedly.
|
|
||||||
pub fn must_cancel_by_type(&mut self, cmd: CommandType) {
|
|
||||||
if self.queued_commands.remove(&cmd).is_none() {
|
|
||||||
println!(
|
|
||||||
"must_cancel_by_type({:?}) didn't find a matching command",
|
|
||||||
cmd
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// This next command might've actually been rescheduled to a later time; the caller won't know
|
/// This next command might've actually been rescheduled to a later time; the caller won't know
|
||||||
/// that here.
|
/// that here.
|
||||||
pub fn peek_next_time(&self) -> Option<Time> {
|
pub fn peek_next_time(&self) -> Option<Time> {
|
||||||
|
Loading…
Reference in New Issue
Block a user