forked from extern/nushell
Shrink Value
by boxing Range
/Closure
(#12784)
# Description On 64-bit platforms the current size of `Value` is 56 bytes. The limiting variants were `Closure` and `Range`. Boxing the two reduces the size of Value to 48 bytes. This is the minimal size possible with our current 16-byte `Span` and any 24-byte `Vec` container which we use in several variants. (Note the extra full 8-bytes necessary for the discriminant or other smaller values due to the 8-byte alignment of `usize`) This is leads to a size reduction of ~15% for `Value` and should overall be beneficial as both `Range` and `Closure` are rarely used compared to the primitive types or even our general container types. # User-Facing Changes Less memory used, potential runtime benefits. (Too late in the evening to run the benchmarks myself right now)
This commit is contained in:
committed by
GitHub
parent
92831d7efc
commit
ba6f38510c
@ -421,7 +421,7 @@ impl PipelineData {
|
||||
)
|
||||
.into_iter(),
|
||||
),
|
||||
Value::Range { val, .. } => PipelineIteratorInner::ListStream(
|
||||
Value::Range { ref val, .. } => PipelineIteratorInner::ListStream(
|
||||
ListStream::new(val.into_range_iter(value.span(), None), val_span, None)
|
||||
.into_iter(),
|
||||
),
|
||||
@ -801,7 +801,7 @@ impl PipelineData {
|
||||
let span = v.span();
|
||||
match v {
|
||||
Value::Range { val, .. } => {
|
||||
match val {
|
||||
match *val {
|
||||
Range::IntRange(range) => {
|
||||
if range.is_unbounded() {
|
||||
return Err(ShellError::GenericError {
|
||||
|
@ -442,7 +442,7 @@ impl FromValue for Spanned<DateTime<FixedOffset>> {
|
||||
impl FromValue for Range {
|
||||
fn from_value(v: Value) -> Result<Self, ShellError> {
|
||||
match v {
|
||||
Value::Range { val, .. } => Ok(val),
|
||||
Value::Range { val, .. } => Ok(*val),
|
||||
v => Err(ShellError::CantConvert {
|
||||
to_type: "range".into(),
|
||||
from_type: v.get_type().to_string(),
|
||||
@ -457,7 +457,7 @@ impl FromValue for Spanned<Range> {
|
||||
fn from_value(v: Value) -> Result<Self, ShellError> {
|
||||
let span = v.span();
|
||||
match v {
|
||||
Value::Range { val, .. } => Ok(Spanned { item: val, span }),
|
||||
Value::Range { val, .. } => Ok(Spanned { item: *val, span }),
|
||||
v => Err(ShellError::CantConvert {
|
||||
to_type: "range".into(),
|
||||
from_type: v.get_type().to_string(),
|
||||
@ -552,7 +552,7 @@ impl FromValue for Record {
|
||||
impl FromValue for Closure {
|
||||
fn from_value(v: Value) -> Result<Self, ShellError> {
|
||||
match v {
|
||||
Value::Closure { val, .. } => Ok(val),
|
||||
Value::Closure { val, .. } => Ok(*val),
|
||||
v => Err(ShellError::CantConvert {
|
||||
to_type: "Closure".into(),
|
||||
from_type: v.get_type().to_string(),
|
||||
@ -567,7 +567,7 @@ impl FromValue for Spanned<Closure> {
|
||||
fn from_value(v: Value) -> Result<Self, ShellError> {
|
||||
let span = v.span();
|
||||
match v {
|
||||
Value::Closure { val, .. } => Ok(Spanned { item: val, span }),
|
||||
Value::Closure { val, .. } => Ok(Spanned { item: *val, span }),
|
||||
v => Err(ShellError::CantConvert {
|
||||
to_type: "Closure".into(),
|
||||
from_type: v.get_type().to_string(),
|
||||
|
@ -86,7 +86,7 @@ pub enum Value {
|
||||
internal_span: Span,
|
||||
},
|
||||
Range {
|
||||
val: Range,
|
||||
val: Box<Range>,
|
||||
// note: spans are being refactored out of Value
|
||||
// please use .span() instead of matching this span value
|
||||
#[serde(rename = "span")]
|
||||
@ -122,7 +122,7 @@ pub enum Value {
|
||||
internal_span: Span,
|
||||
},
|
||||
Closure {
|
||||
val: Closure,
|
||||
val: Box<Closure>,
|
||||
// note: spans are being refactored out of Value
|
||||
// please use .span() instead of matching this span value
|
||||
#[serde(rename = "span")]
|
||||
@ -182,7 +182,7 @@ impl Clone for Value {
|
||||
internal_span: *internal_span,
|
||||
},
|
||||
Value::Range { val, internal_span } => Value::Range {
|
||||
val: *val,
|
||||
val: val.clone(),
|
||||
internal_span: *internal_span,
|
||||
},
|
||||
Value::Float { val, internal_span } => Value::float(*val, *internal_span),
|
||||
@ -327,7 +327,7 @@ impl Value {
|
||||
/// Returns a reference to the inner [`Range`] value or an error if this `Value` is not a range
|
||||
pub fn as_range(&self) -> Result<Range, ShellError> {
|
||||
if let Value::Range { val, .. } = self {
|
||||
Ok(*val)
|
||||
Ok(**val)
|
||||
} else {
|
||||
self.cant_convert_to("range")
|
||||
}
|
||||
@ -336,7 +336,7 @@ impl Value {
|
||||
/// Unwraps the inner [`Range`] value or returns an error if this `Value` is not a range
|
||||
pub fn into_range(self) -> Result<Range, ShellError> {
|
||||
if let Value::Range { val, .. } = self {
|
||||
Ok(val)
|
||||
Ok(*val)
|
||||
} else {
|
||||
self.cant_convert_to("range")
|
||||
}
|
||||
@ -553,7 +553,7 @@ impl Value {
|
||||
/// Unwraps the inner [`Closure`] value or returns an error if this `Value` is not a closure
|
||||
pub fn into_closure(self) -> Result<Closure, ShellError> {
|
||||
if let Value::Closure { val, .. } = self {
|
||||
Ok(val)
|
||||
Ok(*val)
|
||||
} else {
|
||||
self.cant_convert_to("closure")
|
||||
}
|
||||
@ -1012,7 +1012,7 @@ impl Value {
|
||||
});
|
||||
}
|
||||
}
|
||||
Value::Range { val, .. } => {
|
||||
Value::Range { ref val, .. } => {
|
||||
if let Some(item) =
|
||||
val.into_range_iter(current.span(), None).nth(*count)
|
||||
{
|
||||
@ -1826,7 +1826,7 @@ impl Value {
|
||||
|
||||
pub fn range(val: Range, span: Span) -> Value {
|
||||
Value::Range {
|
||||
val,
|
||||
val: val.into(),
|
||||
internal_span: span,
|
||||
}
|
||||
}
|
||||
@ -1862,7 +1862,7 @@ impl Value {
|
||||
|
||||
pub fn closure(val: Closure, span: Span) -> Value {
|
||||
Value::Closure {
|
||||
val,
|
||||
val: val.into(),
|
||||
internal_span: span,
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user