Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 522e5b9

Browse files
committed
restructured the builtin types to be mega fast
1 parent 75e9f04 commit 522e5b9

File tree

12 files changed

+189
-90
lines changed

12 files changed

+189
-90
lines changed

‎Cargo.lock‎

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎Cargo.toml‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ peg = "0.8.4"
88
strum = "0.26.3"
99
strum_macros = "0.26.4"
1010
once_cell = "1.20.2"
11+
mopa = "0.2.2"
1112

1213
[profile.release]
13-
#debug = true
14+
debug = true
1415

‎benchmarker.py‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,12 @@ def benchmark_rs(test):
4545
if __name__ == '__main__':
4646
test_file = "test_deep_for_loop.py"
4747

48-
rs_time = benchmark_rs(test_file)
4948
rusty_time = benchmark_rusty(test_file)
49+
rs_time = benchmark_rs(test_file)
5050
py_time = benchmark_py(test_file)
5151

52-
print(f"RustPython: {rs_time}s")
5352
print(f"RustyPython: {rusty_time}s")
53+
print(f"RustPython: {rs_time}s" )
5454
print(f"CPython: {py_time}s")
55-
print(f"Speedup: {py_time / rusty_time:.2f}x")
55+
print(f"{rusty_time/py_time :.2f}x slower than CPython")
56+
print(f"{rs_time/rusty_time :.2f}x faster than RustPython")

‎flamegraph.svg‎

Lines changed: 1 addition & 1 deletion
Loading[フレーム]

‎src/builtins/object.rs‎

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,33 @@ use crate::builtins::pyobjects::*;
44
use crate::builtins::pyobjects::PyInternalFunction::{InitFunc, NewFunc, UnaryFunc};
55
use crate::pyarena::PyArena;
66

7+
#[derive(Debug)]
8+
pub struct ObjectInstance {
9+
class: Rc<PyClass>
10+
}
11+
12+
impl PyInstance for ObjectInstance {
13+
fn set_field(&mut self, _key: String, _value: PyPointer<PyObject>) {
14+
panic!("Object type has no fields of its own")
15+
}
16+
17+
fn get_field(&self, _key: &str) -> Option<PyPointer<PyObject>> {
18+
panic!("Object type has no fields of its own")
19+
}
20+
21+
fn get_class(&self) -> Rc<PyClass> {
22+
self.class.clone()
23+
}
24+
}
25+
26+
impl ObjectInstance {
27+
pub fn new(py_class: Rc<PyClass>) -> ObjectInstance {
28+
ObjectInstance {
29+
class: py_class
30+
}
31+
}
32+
}
33+
734
pub fn expect_class(pyobj: PyPointer<PyObject>) -> Rc<PyClass> {
835
match *pyobj.borrow() {
936
PyObject::Class(ref class) => class.clone(),
@@ -16,7 +43,7 @@ pub fn object__new__(_arena: &mut PyArena, pyclass: Rc<PyClass>, pyargs: Vec<PyP
1643
panic!("TypeError: object.__new__() takes exactly one argument (the type to instantiate)"); // TODO make python error
1744
}
1845

19-
let pyself = PyPointer::new(PyObject::Instance(PyInstance::new(pyclass)));
46+
let pyself = PyPointer::new(PyObject::Instance(Box::new(ObjectInstance::new(pyclass))));
2047

2148
pyself
2249
}
@@ -35,7 +62,7 @@ pub fn object__repr__(arena: &mut PyArena, pyself: PyPointer<PyObject>) -> PyPoi
3562

3663
pub fn object__str__(arena: &mut PyArena, pyself: PyPointer<PyObject>) -> PyPointer<PyObject> { // by default make str call repr
3764
let str_func = pyself.borrow().get_attribute("__repr__", arena).unwrap();
38-
call_function(str_func, vec![pyself.clone()], &mutPyArena::new())
65+
call_function(str_func, vec![pyself.clone()], arena)
3966
}
4067

4168
pub fn get_object_class() -> PyClass {

‎src/builtins/pyint.rs‎

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,16 @@ pub fn expect_int_ptr(pyobj: PyPointer<PyObject>) -> i64 {
1919
}
2020

2121
pub fn int__new__(_arena: &mut PyArena, _pyclass: Rc<PyClass>, pyargs: Vec<PyPointer<PyObject>>) -> PyPointer<PyObject> { // error handling
22-
let value = pyargs.get(0).unwrap();
22+
let value = pyargs.first().unwrap();
2323

2424
let new_value = match *value.borrow() { // cast value
25-
PyObject::Int(ref value) => value.clone(), // copy the value
25+
PyObject::Int(ref value) => *value, // copy the value
2626
PyObject::Float(ref value) => *value as i64,
2727
PyObject::Str(ref value) => value.parse::<i64>().unwrap(),
2828
_ => panic!("Expected int, str, or float"), // TODO make python error
2929
};
3030

31-
let pyself = PyPointer::new(PyObject::Int(new_value)); // idk how to do inheritance with this
32-
pyself
31+
PyPointer::new(PyObject::Int(new_value)) // I don't know how to do inheritance with this
3332
}
3433

3534
pub fn int__init__(_arena: &mut PyArena, _pyself: PyPointer<PyObject>, _pyargs: Vec<PyPointer<PyObject>>) {

‎src/builtins/pyobjects.rs‎

Lines changed: 34 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use strum::IntoEnumIterator;
88
use strum_macros::EnumIter;
99
use crate::parser::CodeBlock;
1010
use crate::pyarena::PyArena;
11+
use mopa::{mopafy};
1112

1213
#[derive(Clone, Debug, EnumIter)]
1314
pub enum PyMagicMethod {
@@ -146,7 +147,7 @@ impl PyMagicMethods {
146147
}
147148

148149
pub fn set_method(&mut self, magic_method: PyMagicMethod, new_method: Rc<PyInternalFunction>) {
149-
let mutinternal_func= magic_method.get_method_mut(self);
150+
let internal_func= magic_method.get_method_mut(self);
150151

151152
*internal_func = Some(new_method);
152153
}
@@ -300,31 +301,45 @@ pub struct PyFunction {
300301
}
301302

302303
#[derive(Debug)]
303-
pub struct PyInstance {
304+
pub struct PyInstanceGeneric {
304305
class: Rc<PyClass>,
305306
attributes: RwLock<HashMap<String, PyPointer<PyObject>>>,
306-
pub internal_storage: Vec<PyObject>
307+
// pub internal_storage: Vec<PyObject>
307308

308309
}
309310

310-
implPyInstance {
311-
pub fn new(py_class: Rc<PyClass>) -> Self{
312-
PyInstance{
313-
class: py_class,
314-
attributes:RwLock::new(HashMap::new()),
315-
internal_storage:vec![]
316-
}
317-
}
311+
pubtraitPyInstance: mopa::Any + Debug {
312+
// fn new(py_class: Rc<PyClass>) -> Self;
313+
fnset_field(&mutself,key:String,value:PyPointer<PyObject>);
314+
fnget_field(&self,key:&str) -> Option<PyPointer<PyObject>>;
315+
fnget_class(&self) -> Rc<PyClass>;
316+
}
317+
318+
mopafy!(PyInstance);
318319

319-
pub fn set_field(&mut self, key: String, value: PyPointer<PyObject>) {
320-
let mut attributes = self.attributes.get_mut().unwrap_or_else(|e| panic!("Failed to get mutable attributes: {:?}", e));
320+
impl PyInstance for PyInstanceGeneric {
321+
fn set_field(&mut self, key: String, value: PyPointer<PyObject>) {
322+
let attributes = self.attributes.get_mut().unwrap_or_else(|e| panic!("Failed to get mutable attributes: {:?}", e));
321323
let _old_value = attributes.insert(key, value);
322324
}
323325

324-
pubfn get_field(&self, key: &str) -> Option<PyPointer<PyObject>> {
326+
fn get_field(&self, key: &str) -> Option<PyPointer<PyObject>> {
325327
let attributes = self.attributes.read().ok()?;
326328
attributes.get(key).cloned()
327329
}
330+
331+
fn get_class(&self) -> Rc<PyClass> {
332+
self.class.clone()
333+
}
334+
}
335+
336+
impl PyInstanceGeneric {
337+
fn new(py_class: Rc<PyClass>) -> Self {
338+
PyInstanceGeneric {
339+
class: py_class,
340+
attributes: RwLock::new(HashMap::new()),
341+
}
342+
}
328343
}
329344

330345
#[derive(Debug)]
@@ -337,7 +352,7 @@ pub enum PyObject {
337352
// Dict(HashMap<String, PyObject>),
338353
Bool(bool),
339354
Class(Rc<PyClass>),
340-
Instance(PyInstance),
355+
Instance(Box<dynPyInstance>),
341356
Function(PyFunction),
342357
Exception(PyException),
343358
InternalSlot(Rc<PyInternalFunction>),
@@ -348,7 +363,7 @@ pub enum PyObject {
348363
impl PyObject {
349364
pub fn get_class(&self, arena: &mut PyArena) -> Rc<PyClass> {
350365
match self {
351-
PyObject::Instance(py_instance) => py_instance.class.clone(),
366+
PyObject::Instance(py_instance) => py_instance.get_class().clone(),
352367
PyObject::Int(_) => arena.globals.int_class.clone(),
353368
PyObject::Float(_) => {todo!()}
354369
PyObject::Str(_) => {todo!()}
@@ -379,7 +394,7 @@ impl PyObject {
379394
PyObject::Bool(_) => {todo!()}
380395
PyObject::Class(_) => {todo!()}
381396
PyObject::Instance(instance) => {
382-
instance.class.clone().search_for_attribute(py_magic_method)
397+
instance.get_class().clone().search_for_attribute(py_magic_method)
383398
}
384399
PyObject::Function(_) => {todo!()}
385400
PyObject::Exception(_) => {todo!()}
@@ -439,14 +454,14 @@ impl PyObject {
439454
_ => panic!("Expected internal slot"), // TODO make python error
440455
}
441456
}
442-
pub fn expect_instance(&self) -> &PyInstance {
457+
pub fn expect_instance(&self) -> &Box<dynPyInstance> {
443458
match self {
444459
PyObject::Instance(instance) => instance,
445460
_ => panic!("Expected internal slot"), // TODO make python error
446461
}
447462
}
448463

449-
pub fn expect_instance_mut(&mut self) -> &mut PyInstance {
464+
pub fn expect_instance_mut(&mut self) -> &mut Box<dynPyInstance> {
450465
match self {
451466
PyObject::Instance(instance) => instance,
452467
_ => panic!("Expected internal slot"), // TODO make python error

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /