Skip to content
/ coconut Public

Commit e093c9b

Browse files
committedNov 4, 2023
Improve tests perf
1 parent fd5a17f commit e093c9b

File tree

12 files changed

+68
-44
lines changed

12 files changed

+68
-44
lines changed
 

‎.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -145,3 +145,5 @@ __coconut_cache__/
145145
vprof.json
146146
profile.svg
147147
profile.speedscope
148+
runtime_profile.svg
149+
runtime_profile.speedscope

‎Makefile

+9-2
Original file line numberDiff line numberDiff line change
@@ -346,20 +346,27 @@ open-speedscope:
346346
pyspy-purepy: export COCONUT_PURE_PYTHON=TRUE
347347
pyspy-purepy:
348348
py-spy record -o profile.speedscope --format speedscope --subprocesses -- python -m coconut ./coconut/tests/src/cocotest/agnostic ./coconut/tests/dest/cocotest --force
349-
open-speedscope
349+
make open-speedscope
350350

351351
.PHONY: pyspy-native
352352
pyspy-native:
353353
py-spy record -o profile.speedscope --format speedscope --native -- python -m coconut ./coconut/tests/src/cocotest/agnostic ./coconut/tests/dest/cocotest --force --jobs 0
354-
open-speedscope
354+
make open-speedscope
355+
356+
.PHONY: pyspy-runtime
357+
pyspy-runtime:
358+
py-spy record -o runtime_profile.speedscope --format speedscope --subprocesses -- python ./coconut/tests/dest/runner.py
359+
speedscope ./runtime_profile.speedscope
355360

356361
.PHONY: vprof-time
357362
vprof-time:
358363
vprof -c h "./coconut ./coconut/tests/src/cocotest/agnostic ./coconut/tests/dest/cocotest --force --jobs 0 --stack-size 4096 --recursion-limit 4096" --output-file ./vprof.json
364+
make view-vprof
359365

360366
.PHONY: vprof-memory
361367
vprof-memory:
362368
vprof -c m "./coconut ./coconut/tests/src/cocotest/agnostic ./coconut/tests/dest/cocotest --force --jobs 0 --stack-size 4096 --recursion-limit 4096" --output-file ./vprof.json
369+
make view-vprof
363370

364371
.PHONY: view-vprof
365372
view-vprof:

‎__coconut__/__init__.pyi

+2-1
Original file line numberDiff line numberDiff line change
@@ -1750,7 +1750,8 @@ def mapreduce(
17501750
"""
17511751
...
17521752

1753-
_coconut_mapreduce = mapreduce.using_processes = mapreduce.using_threads = mapreduce # type: ignore
1753+
mapreduce.using_processes = mapreduce.using_threads = mapreduce # type: ignore
1754+
_coconut_mapreduce = mapreduce
17541755

17551756

17561757
@_t.overload

‎coconut/command/command.py

+1-8
Original file line numberDiff line numberDiff line change
@@ -134,14 +134,7 @@ class Command(object):
134134
stack_size = 0 # corresponds to --stack-size flag
135135
incremental = False # corresponds to --incremental flag
136136

137-
_prompt = None
138-
139-
@property
140-
def prompt(self):
141-
"""Delay creation of a Prompt() until it's needed."""
142-
if self._prompt is None:
143-
self._prompt = Prompt()
144-
return self._prompt
137+
prompt = Prompt()
145138

146139
def start(self, run=False):
147140
"""Endpoint for coconut and coconut-run."""

‎coconut/command/util.py

+13-2
Original file line numberDiff line numberDiff line change
@@ -495,14 +495,24 @@ class Prompt(object):
495495
session = None
496496
style = None
497497
runner = None
498+
lexer = None
499+
suggester = None if prompt_use_suggester else False
498500

499-
def __init__(self, use_suggester=prompt_use_suggester):
501+
def __init__(self, setup_now=False):
500502
"""Set up the prompt."""
501503
if prompt_toolkit is not None:
502504
self.set_style(os.getenv(style_env_var, default_style))
503505
self.set_history_file(prompt_histfile)
506+
if setup_now:
507+
self.setup()
508+
509+
def setup(self):
510+
"""Actually initialize the underlying Prompt.
511+
We do this lazily since it's expensive."""
512+
if self.lexer is None:
504513
self.lexer = PygmentsLexer(CoconutLexer)
505-
self.suggester = AutoSuggestFromHistory() if use_suggester else None
514+
if self.suggester is None:
515+
self.suggester = AutoSuggestFromHistory()
506516

507517
def set_style(self, style):
508518
"""Set pygments syntax highlighting style."""
@@ -555,6 +565,7 @@ def input(self, more=False):
555565

556566
def prompt(self, msg):
557567
"""Get input using prompt_toolkit."""
568+
self.setup()
558569
try:
559570
# prompt_toolkit v2
560571
if self.session is None:

‎coconut/compiler/header.py

+1
Original file line numberDiff line numberDiff line change
@@ -840,6 +840,7 @@ def async_map(*args, **kwargs):
840840
# -----------------------------------------------------------------------------------------------------------------------
841841

842842

843+
@memoize()
843844
def getheader(which, use_hash, target, no_tco, strict, no_wrap):
844845
"""Generate the specified header.
845846

‎coconut/constants.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,9 @@ def get_path_env_var(env_var, default):
8282
PY310 = sys.version_info >= (3, 10)
8383
PY311 = sys.version_info >= (3, 11)
8484
IPY = (
85-
((PY2 and not PY26) or PY35)
85+
PY35
8686
and (PY37 or not PYPY)
8787
and not (PYPY and WINDOWS)
88-
and not (PY2 and WINDOWS)
8988
and sys.version_info[:2] != (3, 7)
9089
)
9190
MYPY = (

‎coconut/tests/main_test.py

+6-3
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,12 @@
9191

9292
default_recursion_limit = "6144"
9393
default_stack_size = "6144"
94-
95-
# fix EOM on GitHub actions
96-
default_jobs = None if PY36 and not PYPY else "4"
94+
default_jobs = (
95+
# fix EOMs on GitHub actions
96+
"2" if PYPY
97+
else "4" if not PY36
98+
else None
99+
)
97100

98101
jupyter_timeout = 120
99102

‎coconut/tests/src/cocotest/agnostic/primary_1.coco

+14-12
Original file line numberDiff line numberDiff line change
@@ -211,13 +211,6 @@ def primary_test_1() -> bool:
211211
assert map((-), range(5)).iters[0] |> tuple == range(5) |> tuple == zip(range(5), range(6)).iters[0] |> tuple # type: ignore
212212
assert repr(zip((0,1), (1,2))) == "zip((0, 1), (1, 2))"
213213
assert repr(map((-), range(5))).startswith("map(") # type: ignore
214-
assert repr(process_map((-), range(5))).startswith("process_map(") # type: ignore
215-
assert process_map((-), range(5)) |> tuple == (0, -1, -2, -3, -4) == process_map(map$((-)), (range(5),))$[0] |> tuple # type: ignore
216-
assert process_map(zip, (range(2),), (range(2),)) |> map$(tuple) |> tuple == (((0,0), (1,1)),) # type: ignore
217-
assert process_map(zip_longest$(fillvalue=10), (range(1),), (range(2),)) |> map$(tuple) |> tuple == (((0,0), (10,1)),) # type: ignore
218-
assert (range(0, 5), range(5, 10)) |*> map$(+) |> tuple == (5, 7, 9, 11, 13)
219-
assert process_map((*)$(2)..(+)$(1), range(5)) |> tuple == (2, 4, 6, 8, 10)
220-
assert process_map((+), range(5), range(5), chunksize=2) |> list == map((*)$(2), range(5)) |> list == thread_map((+), range(5), range(5), chunksize=2) |> list # type: ignore
221214
assert repr(thread_map((-), range(5))).startswith("thread_map(") # type: ignore
222215
with thread_map.multiple_sequential_calls(max_workers=4): # type: ignore
223216
assert thread_map((-), range(5), stream=True) |> tuple == (0, -1, -2, -3, -4) == thread_map(map$((-)), (range(5),))$[0] |> tuple # type: ignore
@@ -319,7 +312,6 @@ def primary_test_1() -> bool:
319312
assert pow$(?, 2)(3) == 9
320313
assert [] |> reduce$((+), ?, ()) == ()
321314
assert pow$(?, 2) |> repr == "<built-in function pow>$(?, 2)"
322-
assert process_map(pow$(?, 2), range(10)) |> tuple == (0, 1, 4, 9, 16, 25, 36, 49, 64, 81)
323315
assert pow$(?, 2).args == (None, 2)
324316
assert range(20) |> filter$((x) -> x < 5) |> reversed |> tuple == (4,3,2,1,0) == (0,1,2,3,4,5,6,7,8,9) |> filter$((x) -> x < 5) |> reversed |> tuple # type: ignore
325317
assert (range(10) |> map$((x) -> x) |> reversed) `isinstance` map # type: ignore
@@ -1149,10 +1141,6 @@ def primary_test_1() -> bool:
11491141
def __call__(self) = super().__call__()
11501142
HasSuper
11511143
assert HasSuper5.HasHasSuper.HasSuper()() == 10 == HasSuper6().get_HasSuper()()()
1152-
assert process_map((.+(10,)), [
1153-
(a=1, b=2),
1154-
(x=3, y=4),
1155-
]) |> list == [(1, 2, 10), (3, 4, 10)]
11561144
assert f"{'a' + 'b'}" == "ab"
11571145
int_str_tup: (int; str) = (1, "a")
11581146
key = "abc"
@@ -1303,4 +1291,18 @@ def primary_test_1() -> bool:
13031291
assert err is some_err
13041292
assert Expected(error=TypeError()).map_error(const some_err) == Expected(error=some_err)
13051293
assert Expected(10).map_error(const some_err) == Expected(10)
1294+
assert repr(process_map((-), range(5))).startswith("process_map(") # type: ignore
1295+
1296+
with process_map.multiple_sequential_calls(): # type: ignore
1297+
assert process_map((-), range(5)) |> tuple == (0, -1, -2, -3, -4) == process_map(map$((-)), (range(5),))$[0] |> tuple # type: ignore
1298+
assert process_map(zip, (range(2),), (range(2),)) |> map$(tuple) |> tuple == (((0,0), (1,1)),) # type: ignore
1299+
assert process_map(zip_longest$(fillvalue=10), (range(1),), (range(2),)) |> map$(tuple) |> tuple == (((0,0), (10,1)),) # type: ignore
1300+
assert (range(0, 5), range(5, 10)) |*> map$(+) |> tuple == (5, 7, 9, 11, 13)
1301+
assert process_map((*)$(2)..(+)$(1), range(5)) |> tuple == (2, 4, 6, 8, 10)
1302+
assert process_map((+), range(5), range(5), chunksize=2) |> list == map((*)$(2), range(5)) |> list == thread_map((+), range(5), range(5), chunksize=2) |> list # type: ignore
1303+
assert process_map(pow$(?, 2), range(10)) |> tuple == (0, 1, 4, 9, 16, 25, 36, 49, 64, 81)
1304+
assert process_map((.+(10,)), [
1305+
(a=1, b=2),
1306+
(x=3, y=4),
1307+
]) |> list == [(1, 2, 10), (3, 4, 10)]
13061308
return True

‎coconut/tests/src/cocotest/agnostic/primary_2.coco

+9-6
Original file line numberDiff line numberDiff line change
@@ -121,18 +121,12 @@ def primary_test_2() -> bool:
121121
assert flatten([[[1,2]], [[3], [4]]], 2) |> list == [1, 2, 3, 4]
122122
assert flatten([[[1,2]], [[3], [4]]], 2) |> reversed |> list == [4, 3, 2, 1]
123123
assert_raises(-> map((+), range(3), range(4), strict=True) |> list, ValueError) # type: ignore
124-
assert map((+), range(3), range(4)$[:-1], strict=True) |> list == [0, 2, 4] == process_map((+), range(3), range(4)$[:-1], strict=True) |> list # type: ignore
125-
assert range(3) |> map$((.+1), strict=True) |> list == [1, 2, 3] == range(3) |> process_map$((.+1), strict=True) |> list # type: ignore
126124
assert cartesian_product((1, 2), (3, 4), repeat=0) |> list == [()]
127125
assert (a=1, b=2)[1] == 2
128126
obj = object()
129127
assert_raises((def -> obj.abc = 123), AttributeError) # type: ignore
130128
hardref = map((.+1), [1,2,3])
131129
assert weakref.ref(hardref)() |> list == [2, 3, 4] # type: ignore
132-
my_match_err = MatchError("my match error", 123)
133-
assert process_map(ident, [my_match_err]) |> list |> str == str([my_match_err]) # type: ignore
134-
# repeat the same thing again now that my_match_err.str has been called
135-
assert process_map(ident, [my_match_err]) |> list |> str == str([my_match_err]) # type: ignore
136130
match data tuple(1, 2) in (1, 2, 3):
137131
assert False
138132
data TestDefaultMatching(x="x default", y="y default")
@@ -409,4 +403,13 @@ def primary_test_2() -> bool:
409403
assert some_data |> mapreducer == {"a": ["123"], "b": ["567"]}
410404
assert_raises(-> collectby(.[0], [(0, 1), (0, 2)], reduce_func=False), ValueError) # type: ignore
411405
assert ident$(x=?).__name__ == "ident" == ident$(1).__name__ # type: ignore
406+
407+
with process_map.multiple_sequential_calls(): # type: ignore
408+
assert map((+), range(3), range(4)$[:-1], strict=True) |> list == [0, 2, 4] == process_map((+), range(3), range(4)$[:-1], strict=True) |> list # type: ignore
409+
assert range(3) |> map$((.+1), strict=True) |> list == [1, 2, 3] == range(3) |> process_map$((.+1), strict=True) |> list # type: ignore
410+
my_match_err = MatchError("my match error", 123)
411+
assert process_map(ident, [my_match_err]) |> list |> str == str([my_match_err]) # type: ignore
412+
# repeat the same thing again now that my_match_err.str has been called
413+
assert process_map(ident, [my_match_err]) |> list |> str == str([my_match_err]) # type: ignore
414+
412415
return True

‎coconut/tests/src/cocotest/agnostic/suite.coco

+5-3
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@ def suite_test() -> bool:
6767
to_sort = rand_list(10)
6868
assert to_sort |> qsort |> tuple == to_sort |> sorted |> tuple, qsort # type: ignore
6969
to_sort = rand_list(10)
70-
assert process_map(tuple <.. (|>)$(to_sort), qsorts) |> list == [to_sort |> sorted |> tuple] * len(qsorts)
7170
assert repeat(3)$[2] == 3 == repeat_(3)$[2]
7271
assert sum_(repeat(1)$[:5]) == 5 == sum_(repeat_(1)$[:5])
7372
assert (sum_(takewhile((x)-> x<5, N()))
@@ -279,7 +278,6 @@ def suite_test() -> bool:
279278
assert fibs()$[:10] |> list == [1,1,2,3,5,8,13,21,34,55] == fibs_()$[:10] |> list
280279
assert fibs() |> takewhile$((i) -> i < 4000000 ) |> filter$((i) -> i % 2 == 0 ) |> sum == 4613732 == fibs_() |> takewhile$((i) -> i < 4000000 ) |> filter$((i) -> i % 2 == 0 ) |> sum # type: ignore
281280
assert loop([1,2])$[:4] |> list == [1, 2] * 2
282-
assert process_map(list .. .$[:2] .. loop, ([1], [2]))$[:2] |> tuple == ([1, 1], [2, 2])
283281
assert nest("a") |> .$[1] |> .$[1] |> .$[0] == "a"
284282
assert (def -> mod)()(5, 3) == 2
285283
assert sieve((2, 3, 4, 5)) |> list == [2, 3, 5]
@@ -748,7 +746,6 @@ def suite_test() -> bool:
748746
class inh_A() `isinstance` clsA `isinstance` object = inh_A()
749747
for maxdiff in (maxdiff1, maxdiff2, maxdiff3, maxdiff_):
750748
assert maxdiff([7,1,4,5]) == 4, "failed for " + repr(maxdiff)
751-
assert all(r == 4 for r in process_map(call$(?, [7,1,4,5]), [maxdiff1, maxdiff2, maxdiff3]))
752749
assert ret_ret_func(1) == ((), {"func": 1}) == ret_args_kwargs$(func=1)() # type: ignore
753750
assert ret_args_kwargs$(?, func=2)(1) == ((1,), {"func": 2})
754751
assert lift(ret_args_kwargs)(ident, plus1, times2, sq=square)(3) == ((3, 4, 6), {"sq": 9})
@@ -1069,6 +1066,11 @@ forward 2""") == 900
10691066
assert safe_raise_exc(IOError).handle(IOError, const 10).unwrap() == 10 == safe_raise_exc(IOError).expect_error(IOError).result_or(10)
10701067
assert pickle_round_trip(ident$(1))() == 1 == pickle_round_trip(ident$(x=?))(1)
10711068

1069+
with process_map.multiple_sequential_calls(): # type: ignore
1070+
assert process_map(tuple <.. (|>)$(to_sort), qsorts) |> list == [to_sort |> sorted |> tuple] * len(qsorts)
1071+
assert process_map(list .. .$[:2] .. loop, ([1], [2]))$[:2] |> tuple == ([1, 1], [2, 2])
1072+
assert all(r == 4 for r in process_map(call$(?, [7,1,4,5]), [maxdiff1, maxdiff2, maxdiff3]))
1073+
10721074
# must come at end
10731075
assert fibs_calls[0] == 1
10741076
assert lols[0] == 5

‎coconut/tests/src/cocotest/target_sys/target_sys_test.coco

+5-5
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,11 @@ def asyncio_test() -> bool:
4747
def toa(f) = async def (*args, **kwargs) -> f(*args, **kwargs)
4848

4949
async def async_map_0(args):
50-
return process_map(args[0], *args[1:])
51-
async def async_map_1(args) = process_map(args[0], *args[1:])
52-
async def async_map_2([func] + iters) = process_map(func, *iters)
53-
async match def async_map_3([func] + iters) = process_map(func, *iters)
54-
match async def async_map_4([func] + iters) = process_map(func, *iters)
50+
return thread_map(args[0], *args[1:])
51+
async def async_map_1(args) = thread_map(args[0], *args[1:])
52+
async def async_map_2([func] + iters) = thread_map(func, *iters)
53+
async match def async_map_3([func] + iters) = thread_map(func, *iters)
54+
match async def async_map_4([func] + iters) = thread_map(func, *iters)
5555
async def async_map_test() =
5656
for async_map_ in (async_map_0, async_map_1, async_map_2, async_map_3, async_map_4):
5757
assert (await ((pow$(2), range(5)) |> async_map_)) |> tuple == (1, 2, 4, 8, 16)

0 commit comments

Comments
 (0)
Please sign in to comment.