Skip to content

Commit b995a5f

Browse files
authored
Merge pull request #2476 from pca006132/master
Optimize method call performance
2 parents bfaf824 + dbe7203 commit b995a5f

File tree

3 files changed

+21
-8
lines changed

3 files changed

+21
-8
lines changed

vm/src/builtins/pytype.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -629,7 +629,7 @@ fn subtype_get_dict(obj: PyObjectRef, vm: &VirtualMachine) -> PyResult {
629629
// TODO: obj.class().as_pyref() need to be supported
630630
let cls = obj.clone_class();
631631
let ret = match find_base_dict_descr(&cls, vm) {
632-
Some(descr) => vm.call_get_descriptor(descr, obj).unwrap_or_else(|| {
632+
Some(descr) => vm.call_get_descriptor(descr, obj).unwrap_or_else(|_| {
633633
Err(vm.new_type_error(format!(
634634
"this __dict__ descriptor does not support '{}' objects",
635635
cls.name

vm/src/function.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ where
2626
}
2727
}
2828

29+
macro_rules! count {
30+
() => (0usize);
31+
( $x:tt $($xs:tt)* ) => (1usize + count!($($xs)*));
32+
}
33+
2934
// A tuple of values that each implement `IntoPyObject` represents a sequence of
3035
// arguments that can be bound and passed to a built-in function.
3136
macro_rules! into_func_args_from_tuple {
@@ -37,7 +42,9 @@ macro_rules! into_func_args_from_tuple {
3742
#[inline]
3843
fn into_args(self, vm: &VirtualMachine) -> FuncArgs {
3944
let ($($n,)*) = self;
40-
vec![$($n.into_pyobject(vm),)*].into()
45+
let mut result = Vec::with_capacity(count!($($n,)*) + 1);
46+
$(result.push($n.into_pyobject(vm), );)*
47+
result.into()
4148
}
4249
}
4350
};

vm/src/vm.rs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -944,19 +944,25 @@ impl VirtualMachine {
944944
descr: PyObjectRef,
945945
obj: Option<PyObjectRef>,
946946
cls: Option<PyObjectRef>,
947-
) -> Option<PyResult> {
947+
) -> Result<PyResult, PyObjectRef> {
948948
let descr_get = descr.class().mro_find_map(|cls| cls.slots.descr_get.load());
949-
descr_get.map(|descr_get| descr_get(descr, obj, cls, self))
949+
match descr_get {
950+
Some(descr_get) => Ok(descr_get(descr, obj, cls, self)),
951+
None => Err(descr),
952+
}
950953
}
951954

952-
pub fn call_get_descriptor(&self, descr: PyObjectRef, obj: PyObjectRef) -> Option<PyResult> {
955+
pub fn call_get_descriptor(
956+
&self,
957+
descr: PyObjectRef,
958+
obj: PyObjectRef,
959+
) -> Result<PyResult, PyObjectRef> {
953960
let cls = obj.clone_class().into_object();
954961
self.call_get_descriptor_specific(descr, Some(obj), Some(cls))
955962
}
956963

957964
pub fn call_if_get_descriptor(&self, attr: PyObjectRef, obj: PyObjectRef) -> PyResult {
958-
self.call_get_descriptor(attr.clone(), obj)
959-
.unwrap_or(Ok(attr))
965+
self.call_get_descriptor(attr, obj).unwrap_or_else(Ok)
960966
}
961967

962968
pub fn call_method<T>(&self, obj: &PyObjectRef, method_name: &str, args: T) -> PyResult
@@ -1257,7 +1263,7 @@ impl VirtualMachine {
12571263

12581264
if let Some(ref attr) = cls_attr {
12591265
if attr.class().has_attr("__set__") {
1260-
if let Some(r) = self.call_get_descriptor(attr.clone(), obj.clone()) {
1266+
if let Ok(r) = self.call_get_descriptor(attr.clone(), obj.clone()) {
12611267
return r.map(Some);
12621268
}
12631269
}

0 commit comments

Comments
 (0)