message: Turn `Workspace::is_member` into an `O(1)` query
  This commit moves it from a linear query which does a lot of hashing of
  `PathBuf` to an `O(1)` query that only hashes `PackageId`. This improves
  Servo's null build performance by 50ms or so, causing a number of
  functions to disappear from profiles.
diff: use std::cell::RefCell;
  use std::collections::hash_map::{Entry, HashMap};
  -use std::collections::BTreeMap;
  +use std::collections::{BTreeMap, HashSet};
  use std::path::{Path, PathBuf};
  use std::slice;
  @@ -10,7 +10,7 @@ use url::Url;
  use crate::core::profiles::Profiles;
  use crate::core::registry::PackageRegistry;
  -use crate::core::{Dependency, PackageIdSpec};
  +use crate::core::{Dependency, PackageIdSpec, PackageId};
  use crate::core::{EitherManifest, Package, SourceId, VirtualManifest};
  use crate::ops;
  use crate::sources::PathSource;
  @@ -51,6 +51,7 @@ pub struct Workspace<'cfg> {
  // paths. The packages themselves can be looked up through the `packages`
  // set above.
  members: Vec<PathBuf>,
  + member_ids: HashSet<PackageId>,
  // The subset of `members` that are used by the
  // `build`, `check`, `test`, and `bench` subcommands
  @@ -148,6 +149,7 @@ impl<'cfg> Workspace<'cfg> {
  root_manifest: None,
  target_dir,
  members: Vec::new(),
  + member_ids: HashSet::new(),
  default_members: Vec::new(),
  is_ephemeral: false,
  require_optional_deps: true,
  @@ -185,6 +187,7 @@ impl<'cfg> Workspace<'cfg> {
  root_manifest: None,
  target_dir: None,
  members: Vec::new(),
  + member_ids: HashSet::new(),
  default_members: Vec::new(),
  is_ephemeral: true,
  require_optional_deps,
  @@ -193,6 +196,7 @@ impl<'cfg> Workspace<'cfg> {
  };
  {
  let key = ws.current_manifest.parent().unwrap();
  + let id = package.package_id();
  let package = MaybePackage::Package(package);
  ws.packages.packages.insert(key.to_path_buf(), package);
  ws.target_dir = if let Some(dir) = target_dir {
  @@ -201,6 +205,7 @@ impl<'cfg> Workspace<'cfg> {
  ws.config.target_dir()?
  };
  ws.members.push(ws.current_manifest.clone());
  + ws.member_ids.insert(id);
  ws.default_members.push(ws.current_manifest.clone());
  }
  Ok(ws)
  @@ -315,7 +320,7 @@ impl<'cfg> Workspace<'cfg> {
  /// Returns true if the package is a member of the workspace.
  pub fn is_member(&self, pkg: &Package) -> bool {
  - self.members().any(|p| p == pkg)
  + self.member_ids.contains(&pkg.package_id())
  }
  pub fn is_ephemeral(&self) -> bool {
  @@ -430,6 +435,10 @@ impl<'cfg> Workspace<'cfg> {
  debug!("find_members - only me as a member");
  self.members.push(self.current_manifest.clone());
  self.default_members.push(self.current_manifest.clone());
  + if let Ok(pkg) = self.current() {
  + let id = pkg.package_id();
  + self.member_ids.insert(id);
  + }
  return Ok(());
  }
  };
  @@ -515,6 +524,7 @@ impl<'cfg> Workspace<'cfg> {
  MaybePackage::Package(ref p) => p,
  MaybePackage::Virtual(_) => return Ok(()),
  };
  + self.member_ids.insert(pkg.package_id());
  pkg.dependencies()
  .iter()
  .map(|d| d.source_id())
  