optimize avoid lookup for builtin iter and reversed

This commit is contained in:
Kangzhi Shi
2021-09-28 07:58:22 +02:00
parent 8b9c33c12a
commit fa8df88b5d
5 changed files with 20 additions and 10 deletions

View File

@@ -10,7 +10,7 @@ use crate::{
ItemProtocol, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol,
VirtualMachine,
};
use rustpython_common::lock::{PyMutex, PyRwLock, PyRwLockUpgradableReadGuard};
use rustpython_common::lock::{OnceCell, PyMutex, PyRwLock, PyRwLockUpgradableReadGuard};
/// Marks status of iterator.
#[derive(Debug, Clone)]
@@ -69,7 +69,7 @@ impl<T> PositionIterInternal<T> {
where
F: FnOnce(&T) -> PyObjectRef,
{
let iter = vm.get_attribute(vm.builtins.clone(), "iter").unwrap();
let iter = get_builtin_attribute_iter(vm).clone();
self._reduce(iter, f, vm)
}
@@ -77,7 +77,7 @@ impl<T> PositionIterInternal<T> {
where
F: FnOnce(&T) -> PyObjectRef,
{
let reversed = vm.get_attribute(vm.builtins.clone(), "reversed").unwrap();
let reversed = get_builtin_attribute_reversed(vm).clone();
self._reduce(reversed, f, vm)
}
@@ -167,6 +167,16 @@ impl<T> PositionIterInternal<T> {
}
}
pub fn get_builtin_attribute_iter(vm: &VirtualMachine) -> &PyObjectRef {
static INSTANCE: OnceCell<PyObjectRef> = OnceCell::new();
INSTANCE.get_or_init(|| vm.get_attribute(vm.builtins.clone(), "iter").unwrap())
}
pub fn get_builtin_attribute_reversed(vm: &VirtualMachine) -> &PyObjectRef {
static INSTANCE: OnceCell<PyObjectRef> = OnceCell::new();
INSTANCE.get_or_init(|| vm.get_attribute(vm.builtins.clone(), "reversed").unwrap())
}
#[pyclass(module = false, name = "iterator")]
#[derive(Debug)]
pub struct PySequenceIterator {

View File

@@ -25,6 +25,7 @@ use rustpython_common::{
ascii,
atomic::{self, PyAtomic, Radium},
hash,
lock::PyMutex,
};
use std::mem::size_of;
use std::ops::Range;

View File

@@ -1,4 +1,5 @@
use super::{PyInt, PyIntRef, PySlice, PySliceRef, PyTypeRef};
use crate::builtins::get_builtin_attribute_iter;
use crate::common::hash::PyHash;
use crate::{
function::{FuncArgs, OptionalArg},
@@ -608,7 +609,7 @@ fn range_iter_reduce(
index: usize,
vm: &VirtualMachine,
) -> PyResult {
let iter = vm.get_attribute(vm.builtins.clone(), "iter")?;
let iter = get_builtin_attribute_iter(vm).clone();
let stop = start.clone() + length * step.clone();
let range = PyRange {
start: PyInt::from(start).into_ref(vm),

View File

@@ -1,9 +1,8 @@
use super::PositionIterInternal;
/*
* Builtin set type with a sequence of unique items.
*/
use super::{IterStatus, PyDictRef, PyTypeRef};
use crate::common::{ascii, hash::PyHash, rc::PyRc};
use super::{get_builtin_attribute_iter, IterStatus, PositionIterInternal, PyDictRef, PyTypeRef};
use crate::common::{ascii, hash::PyHash, lock::PyMutex, rc::PyRc};
use crate::{
dictdatatype::{self, DictSize},
function::{ArgIterable, FuncArgs, OptionalArg, PosArgs},
@@ -16,7 +15,6 @@ use crate::{
IdProtocol, PyClassImpl, PyComparisonValue, PyContext, PyObjectRef, PyRef, PyResult, PyValue,
TryFromObject, TypeProtocol,
};
use rustpython_common::lock::PyMutex;
use std::fmt;
pub type SetContentType = dictdatatype::Dict<()>;
@@ -842,7 +840,7 @@ impl PySetIterator {
fn reduce(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyResult<(PyObjectRef, (PyObjectRef,))> {
let internal = zelf.internal.lock();
Ok((
vm.get_attribute(vm.builtins.clone(), "iter")?,
get_builtin_attribute_iter(vm).clone(),
(vm.ctx.new_list(match &internal.status {
IterStatus::Exhausted => vec![],
IterStatus::Active(dict) => {

View File

@@ -1,8 +1,8 @@
use crate::builtins::{PyStr, PyStrRef};
/// Ordered dictionary implementation.
/// Inspired by: https://morepypy.blogspot.com/2015/01/faster-more-memory-efficient-and-more.html
/// And: https://www.youtube.com/watch?v=p33CVV29OG8
/// And: http://code.activestate.com/recipes/578375/
use crate::builtins::{PyStr, PyStrRef};
use crate::common::{
hash,
lock::{PyRwLock, PyRwLockReadGuard, PyRwLockWriteGuard},