Skip to content

Commit 59c0aeb

Browse files
authored
Merge pull request RustPython#3725 from youknowone/opt-nth
Optimize comprehension item add operations
2 parents b289aa5 + d58ddd2 commit 59c0aeb

File tree

3 files changed

+20
-39
lines changed

3 files changed

+20
-39
lines changed

bytecode/src/lib.rs

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -393,13 +393,6 @@ pub enum Instruction {
393393
GetAIter,
394394
GetANext,
395395
EndAsyncFor,
396-
397-
/// Reverse order evaluation in MapAdd
398-
/// required to support named expressions of Python 3.8 in dict comprehension
399-
/// today (including Py3.9) only required in dict comprehension.
400-
MapAddRev {
401-
i: u32,
402-
},
403396
}
404397

405398
use self::Instruction::*;
@@ -1024,7 +1017,7 @@ impl Instruction {
10241017
}
10251018
BuildSlice { step } => -2 - (*step as i32) + 1,
10261019
ListAppend { .. } | SetAdd { .. } => -1,
1027-
MapAdd { .. } | MapAddRev { .. } => -2,
1020+
MapAdd { .. } => -2,
10281021
PrintExpr => -1,
10291022
LoadBuildClass => 1,
10301023
UnpackSequence { size } => -1 + *size as i32,
@@ -1187,7 +1180,7 @@ impl Instruction {
11871180
BuildSlice { step } => w!(BuildSlice, step),
11881181
ListAppend { i } => w!(ListAppend, i),
11891182
SetAdd { i } => w!(SetAdd, i),
1190-
MapAddRev { i } => w!(MapAddRev, i),
1183+
MapAdd { i } => w!(MapAdd, i),
11911184
PrintExpr => w!(PrintExpr),
11921185
LoadBuildClass => w!(LoadBuildClass),
11931186
UnpackSequence { size } => w!(UnpackSequence, size),
@@ -1199,7 +1192,6 @@ impl Instruction {
11991192
GetAIter => w!(GetAIter),
12001193
GetANext => w!(GetANext),
12011194
EndAsyncFor => w!(EndAsyncFor),
1202-
MapAdd { i } => w!(MapAdd, i),
12031195
}
12041196
}
12051197
}

compiler/src/compile.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2095,7 +2095,7 @@ impl Compiler {
20952095
&|compiler| {
20962096
compiler.compile_comprehension_element(elt)?;
20972097
compiler.emit(Instruction::ListAppend {
2098-
i: (1 + generators.len()) as u32,
2098+
i: generators.len() as u32,
20992099
});
21002100
Ok(())
21012101
},
@@ -2112,7 +2112,7 @@ impl Compiler {
21122112
&|compiler| {
21132113
compiler.compile_comprehension_element(elt)?;
21142114
compiler.emit(Instruction::SetAdd {
2115-
i: (1 + generators.len()) as u32,
2115+
i: generators.len() as u32,
21162116
});
21172117
Ok(())
21182118
},
@@ -2136,8 +2136,8 @@ impl Compiler {
21362136
compiler.compile_expression(key)?;
21372137
compiler.compile_expression(value)?;
21382138

2139-
compiler.emit(Instruction::MapAddRev {
2140-
i: (1 + generators.len()) as u32,
2139+
compiler.emit(Instruction::MapAdd {
2140+
i: generators.len() as u32,
21412141
});
21422142

21432143
Ok(())

vm/src/frame.rs

Lines changed: 14 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::{
44
asyncgenerator::PyAsyncGenWrappedValue,
55
function::{PyCell, PyCellRef, PyFunction},
66
tuple::{PyTuple, PyTupleTyped},
7-
PyBaseExceptionRef, PyCode, PyCoroutine, PyDict, PyDictRef, PyGenerator, PyListRef, PySet,
7+
PyBaseExceptionRef, PyCode, PyCoroutine, PyDict, PyDictRef, PyGenerator, PyList, PySet,
88
PySlice, PyStr, PyStrRef, PyTraceback, PyTypeRef,
99
},
1010
bytecode,
@@ -668,45 +668,33 @@ impl ExecutingFrame<'_> {
668668
} => self.execute_build_map(vm, *size, *unpack, *for_call),
669669
bytecode::Instruction::BuildSlice { step } => self.execute_build_slice(vm, *step),
670670
bytecode::Instruction::ListAppend { i } => {
671+
let item = self.pop_value();
671672
let obj = self.nth_value(*i);
672-
let list: PyListRef = unsafe {
673+
let list: &Py<PyList> = unsafe {
673674
// SAFETY: trust compiler
674-
obj.downcast_unchecked()
675+
obj.downcast_unchecked_ref()
675676
};
676-
let item = self.pop_value();
677677
list.append(item);
678678
Ok(None)
679679
}
680680
bytecode::Instruction::SetAdd { i } => {
681+
let item = self.pop_value();
681682
let obj = self.nth_value(*i);
682-
let set: PyRef<PySet> = unsafe {
683+
let set: &Py<PySet> = unsafe {
683684
// SAFETY: trust compiler
684-
obj.downcast_unchecked()
685+
obj.downcast_unchecked_ref()
685686
};
686-
let item = self.pop_value();
687687
set.add(item, vm)?;
688688
Ok(None)
689689
}
690690
bytecode::Instruction::MapAdd { i } => {
691-
let obj = self.nth_value(*i + 1);
692-
let dict: PyDictRef = unsafe {
693-
// SAFETY: trust compiler
694-
obj.downcast_unchecked()
695-
};
696-
let key = self.pop_value();
697691
let value = self.pop_value();
698-
dict.set_item(&*key, value, vm)?;
699-
Ok(None)
700-
}
701-
bytecode::Instruction::MapAddRev { i } => {
702-
// change order of evalutio of key and value to support Py3.8 Named expressions in dict comprehension
703-
let obj = self.nth_value(*i + 1);
704-
let dict: PyDictRef = unsafe {
692+
let key = self.pop_value();
693+
let obj = self.nth_value(*i);
694+
let dict: &Py<PyDict> = unsafe {
705695
// SAFETY: trust compiler
706-
obj.downcast_unchecked()
696+
obj.downcast_unchecked_ref()
707697
};
708-
let value = self.pop_value();
709-
let key = self.pop_value();
710698
dict.set_item(&*key, value, vm)?;
711699
Ok(None)
712700
}
@@ -1811,8 +1799,9 @@ impl ExecutingFrame<'_> {
18111799
}
18121800

18131801
#[inline]
1814-
fn nth_value(&self, depth: u32) -> PyObjectRef {
1815-
self.state.stack[self.state.stack.len() - depth as usize - 1].clone()
1802+
fn nth_value(&self, depth: u32) -> &PyObject {
1803+
let stack = &self.state.stack;
1804+
&stack[stack.len() - depth as usize - 1]
18161805
}
18171806

18181807
#[cold]

0 commit comments

Comments
 (0)