Skip to content

Commit ae8ea1d

Browse files
Merge remote-tracking branch 'origin/master' into joey/proper-titlecase
2 parents 29ea307 + 19be5c9 commit ae8ea1d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+1176
-368
lines changed

benchmarks/README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
2+
# Benchmarking
3+
4+
These are some files to determine performance of rustpython.
5+
6+
# Usage
7+
8+
Install pytest and pytest-benchmark:
9+
10+
$ pip install pytest-benchmark
11+
12+
Then run:
13+
14+
$ pytest
15+
16+
# Benchmark source
17+
18+
- https://benchmarksgame-team.pages.debian.net/benchmarksgame/program/nbody-python3-2.html
19+

benchmarks/benchmarks/mandelbrot.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#!/usr/bin/env python3
2+
# coding: utf-8
3+
4+
w = 50.0
5+
h = 50.0
6+
7+
y = 0.0
8+
while y < h:
9+
x = 0.0
10+
while x < w:
11+
Zr, Zi, Tr, Ti = 0.0, 0.0, 0.0, 0.0
12+
Cr = 2*x/w - 1.5
13+
Ci = 2*y/h - 1.0
14+
15+
i = 0
16+
while i < 50 and Tr+Ti <= 4:
17+
Zi = 2*Zr*Zi + Ci
18+
Zr = Tr - Ti + Cr
19+
Tr = Zr * Zr
20+
Ti = Zi * Zi
21+
i = i+1
22+
23+
if Tr+Ti <= 4:
24+
print('*', end='')
25+
else:
26+
print('·', end='')
27+
28+
x = x+1
29+
30+
print()
31+
y = y+1

benchmarks/benchmarks/nbody.py

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
2+
# The Computer Language Benchmarks Game
3+
# https://salsa.debian.org/benchmarksgame-team/benchmarksgame/
4+
#
5+
# originally by Kevin Carson
6+
# modified by Tupteq, Fredrik Johansson, and Daniel Nanz
7+
# modified by Maciej Fijalkowski
8+
# 2to3
9+
# modified by Andriy Misyura
10+
11+
from math import sqrt
12+
13+
def combinations(l):
14+
result = []
15+
for x in range(len(l) - 1):
16+
ls = l[x+1:]
17+
for y in ls:
18+
result.append((l[x][0],l[x][1],l[x][2],y[0],y[1],y[2]))
19+
return result
20+
21+
PI = 3.14159265358979323
22+
SOLAR_MASS = 4 * PI * PI
23+
DAYS_PER_YEAR = 365.24
24+
25+
BODIES = {
26+
'sun': ([0.0, 0.0, 0.0], [0.0, 0.0, 0.0], SOLAR_MASS),
27+
28+
'jupiter': ([4.84143144246472090e+00,
29+
-1.16032004402742839e+00,
30+
-1.03622044471123109e-01],
31+
[1.66007664274403694e-03 * DAYS_PER_YEAR,
32+
7.69901118419740425e-03 * DAYS_PER_YEAR,
33+
-6.90460016972063023e-05 * DAYS_PER_YEAR],
34+
9.54791938424326609e-04 * SOLAR_MASS),
35+
36+
'saturn': ([8.34336671824457987e+00,
37+
4.12479856412430479e+00,
38+
-4.03523417114321381e-01],
39+
[-2.76742510726862411e-03 * DAYS_PER_YEAR,
40+
4.99852801234917238e-03 * DAYS_PER_YEAR,
41+
2.30417297573763929e-05 * DAYS_PER_YEAR],
42+
2.85885980666130812e-04 * SOLAR_MASS),
43+
44+
'uranus': ([1.28943695621391310e+01,
45+
-1.51111514016986312e+01,
46+
-2.23307578892655734e-01],
47+
[2.96460137564761618e-03 * DAYS_PER_YEAR,
48+
2.37847173959480950e-03 * DAYS_PER_YEAR,
49+
-2.96589568540237556e-05 * DAYS_PER_YEAR],
50+
4.36624404335156298e-05 * SOLAR_MASS),
51+
52+
'neptune': ([1.53796971148509165e+01,
53+
-2.59193146099879641e+01,
54+
1.79258772950371181e-01],
55+
[2.68067772490389322e-03 * DAYS_PER_YEAR,
56+
1.62824170038242295e-03 * DAYS_PER_YEAR,
57+
-9.51592254519715870e-05 * DAYS_PER_YEAR],
58+
5.15138902046611451e-05 * SOLAR_MASS) }
59+
60+
SYSTEM = tuple(BODIES.values())
61+
PAIRS = tuple(combinations(SYSTEM))
62+
63+
def advance(dt, n, bodies=SYSTEM, pairs=PAIRS):
64+
for i in range(n):
65+
for ([x1, y1, z1], v1, m1, [x2, y2, z2], v2, m2) in pairs:
66+
dx = x1 - x2
67+
dy = y1 - y2
68+
dz = z1 - z2
69+
dist = sqrt(dx * dx + dy * dy + dz * dz);
70+
mag = dt / (dist*dist*dist)
71+
b1m = m1 * mag
72+
b2m = m2 * mag
73+
v1[0] -= dx * b2m
74+
v1[1] -= dy * b2m
75+
v1[2] -= dz * b2m
76+
v2[2] += dz * b1m
77+
v2[1] += dy * b1m
78+
v2[0] += dx * b1m
79+
for (r, [vx, vy, vz], m) in bodies:
80+
r[0] += dt * vx
81+
r[1] += dt * vy
82+
r[2] += dt * vz
83+
84+
def report_energy(bodies=SYSTEM, pairs=PAIRS, e=0.0):
85+
for ((x1, y1, z1), v1, m1, (x2, y2, z2), v2, m2) in pairs:
86+
dx = x1 - x2
87+
dy = y1 - y2
88+
dz = z1 - z2
89+
e -= (m1 * m2) / ((dx * dx + dy * dy + dz * dz) ** 0.5)
90+
for (r, [vx, vy, vz], m) in bodies:
91+
e += m * (vx * vx + vy * vy + vz * vz) / 2.
92+
print(f"{e}")
93+
94+
def offset_momentum(ref, bodies=SYSTEM, px=0.0, py=0.0, pz=0.0):
95+
for (r, [vx, vy, vz], m) in bodies:
96+
px -= vx * m
97+
py -= vy * m
98+
pz -= vz * m
99+
(r, v, m) = ref
100+
v[0] = px / m
101+
v[1] = py / m
102+
v[2] = pz / m
103+
104+
def main(n, ref='sun'):
105+
offset_momentum(BODIES[ref])
106+
report_energy()
107+
advance(0.01, n)
108+
report_energy()
109+
110+
main(500)

benchmarks/test_benchmarks.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
2+
import time
3+
import sys
4+
5+
import pytest
6+
import subprocess
7+
8+
from benchmarks import nbody
9+
10+
# Interpreters:
11+
rustpython_exe = '../target/release/rustpython'
12+
cpython_exe = sys.executable
13+
pythons = [
14+
cpython_exe,
15+
rustpython_exe
16+
]
17+
18+
# Benchmark scripts:
19+
benchmarks = [
20+
['benchmarks/nbody.py'],
21+
['benchmarks/mandelbrot.py'],
22+
]
23+
24+
@pytest.mark.parametrize('exe', pythons)
25+
@pytest.mark.parametrize('args', benchmarks)
26+
def test_bench(exe, args, benchmark):
27+
def bench():
28+
subprocess.run([exe] + args)
29+
30+
benchmark(bench)
31+

derive/src/error.rs

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
// Taken from https://github.com/rustwasm/wasm-bindgen/blob/master/crates/backend/src/error.rs
2+
//
3+
// Copyright (c) 2014 Alex Crichton
4+
//
5+
// Permission is hereby granted, free of charge, to any
6+
// person obtaining a copy of this software and associated
7+
// documentation files (the "Software"), to deal in the
8+
// Software without restriction, including without
9+
// limitation the rights to use, copy, modify, merge,
10+
// publish, distribute, sublicense, and/or sell copies of
11+
// the Software, and to permit persons to whom the Software
12+
// is furnished to do so, subject to the following
13+
// conditions:
14+
//
15+
// The above copyright notice and this permission notice
16+
// shall be included in all copies or substantial portions
17+
// of the Software.
18+
//
19+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
20+
// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
21+
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
22+
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
23+
// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
24+
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25+
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
26+
// IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27+
// DEALINGS IN THE SOFTWARE.
28+
#![allow(dead_code)]
29+
30+
use proc_macro2::*;
31+
use quote::{ToTokens, TokenStreamExt};
32+
use syn::parse::Error;
33+
34+
macro_rules! err_span {
35+
($span:expr, $($msg:tt)*) => (
36+
$crate::Diagnostic::spanned_error(&$span, format!($($msg)*))
37+
)
38+
}
39+
40+
macro_rules! bail_span {
41+
($($t:tt)*) => (
42+
return Err(err_span!($($t)*).into())
43+
)
44+
}
45+
46+
macro_rules! push_err_span {
47+
($diagnostics:expr, $($t:tt)*) => {
48+
$diagnostics.push(err_span!($($t)*))
49+
};
50+
}
51+
52+
#[derive(Debug)]
53+
pub struct Diagnostic {
54+
inner: Repr,
55+
}
56+
57+
#[derive(Debug)]
58+
enum Repr {
59+
Single {
60+
text: String,
61+
span: Option<(Span, Span)>,
62+
},
63+
SynError(Error),
64+
Multi {
65+
diagnostics: Vec<Diagnostic>,
66+
},
67+
}
68+
69+
impl Diagnostic {
70+
pub fn error<T: Into<String>>(text: T) -> Diagnostic {
71+
Diagnostic {
72+
inner: Repr::Single {
73+
text: text.into(),
74+
span: None,
75+
},
76+
}
77+
}
78+
79+
pub fn span_error<T: Into<String>>(span: Span, text: T) -> Diagnostic {
80+
Diagnostic {
81+
inner: Repr::Single {
82+
text: text.into(),
83+
span: Some((span, span)),
84+
},
85+
}
86+
}
87+
88+
pub fn spanned_error<T: Into<String>>(node: &ToTokens, text: T) -> Diagnostic {
89+
Diagnostic {
90+
inner: Repr::Single {
91+
text: text.into(),
92+
span: extract_spans(node),
93+
},
94+
}
95+
}
96+
97+
pub fn from_vec(diagnostics: Vec<Diagnostic>) -> Result<(), Diagnostic> {
98+
if diagnostics.len() == 0 {
99+
Ok(())
100+
} else {
101+
Err(Diagnostic {
102+
inner: Repr::Multi { diagnostics },
103+
})
104+
}
105+
}
106+
107+
#[allow(unconditional_recursion)]
108+
pub fn panic(&self) -> ! {
109+
match &self.inner {
110+
Repr::Single { text, .. } => panic!("{}", text),
111+
Repr::SynError(error) => panic!("{}", error),
112+
Repr::Multi { diagnostics } => diagnostics[0].panic(),
113+
}
114+
}
115+
}
116+
117+
impl From<Error> for Diagnostic {
118+
fn from(err: Error) -> Diagnostic {
119+
Diagnostic {
120+
inner: Repr::SynError(err),
121+
}
122+
}
123+
}
124+
125+
fn extract_spans(node: &ToTokens) -> Option<(Span, Span)> {
126+
let mut t = TokenStream::new();
127+
node.to_tokens(&mut t);
128+
let mut tokens = t.into_iter();
129+
let start = tokens.next().map(|t| t.span());
130+
let end = tokens.last().map(|t| t.span());
131+
start.map(|start| (start, end.unwrap_or(start)))
132+
}
133+
134+
impl ToTokens for Diagnostic {
135+
fn to_tokens(&self, dst: &mut TokenStream) {
136+
match &self.inner {
137+
Repr::Single { text, span } => {
138+
let cs2 = (Span::call_site(), Span::call_site());
139+
let (start, end) = span.unwrap_or(cs2);
140+
dst.append(Ident::new("compile_error", start));
141+
dst.append(Punct::new('!', Spacing::Alone));
142+
let mut message = TokenStream::new();
143+
message.append(Literal::string(text));
144+
let mut group = Group::new(Delimiter::Brace, message);
145+
group.set_span(end);
146+
dst.append(group);
147+
}
148+
Repr::Multi { diagnostics } => {
149+
for diagnostic in diagnostics {
150+
diagnostic.to_tokens(dst);
151+
}
152+
}
153+
Repr::SynError(err) => {
154+
err.to_compile_error().to_tokens(dst);
155+
}
156+
}
157+
}
158+
}

0 commit comments

Comments
 (0)