|
| 1 | +from concurrent.futures import ThreadPoolExecutor |
| 2 | + |
| 3 | +import psutil |
1 | 4 | from outlines_core.fsm.guide import RegexGuide
|
2 | 5 |
|
3 | 6 | from .common import setup_tokenizer
|
@@ -25,6 +28,28 @@ def setup(self, pattern_name):
|
25 | 28 | def time_regex_to_guide(self, pattern_name):
|
26 | 29 | RegexGuide.from_regex(self.pattern, self.tokenizer)
|
27 | 30 |
|
| 31 | + def time_regex_to_guide_parallel(self, pattern_name): |
| 32 | + # Default GIL switch interval is 5ms (0.005), which isn't helpful for cpu heavy tasks, |
| 33 | + # this parallel case should be relatively close in runtime to one thread, but it is not, |
| 34 | + # because of the GIL. |
| 35 | + core_count = psutil.cpu_count(logical=False) |
| 36 | + with ThreadPoolExecutor(max_workers=core_count) as executor: |
| 37 | + list(executor.map(self._from_regex, [pattern_name] * core_count)) |
| 38 | + |
| 39 | + def time_regex_to_guide_parallel_with_custom_switch_interval(self, pattern_name): |
| 40 | + # This test is to show, that if GIL's switch interval is set to be longer, then the parallel |
| 41 | + # test's runtime on physical cores will be much closer to the one-threaded case. |
| 42 | + import sys |
| 43 | + |
| 44 | + sys.setswitchinterval(5) |
| 45 | + |
| 46 | + core_count = psutil.cpu_count(logical=False) |
| 47 | + with ThreadPoolExecutor(max_workers=core_count) as executor: |
| 48 | + list(executor.map(self._from_regex, [pattern_name] * core_count)) |
| 49 | + |
| 50 | + def _from_regex(self, pattern_name): |
| 51 | + RegexGuide.from_regex(self.pattern, self.tokenizer) |
| 52 | + |
28 | 53 |
|
29 | 54 | class MemoryRegexGuideBenchmark:
|
30 | 55 | params = ["simple_phone", "complex_span_constrained_relation_extraction"]
|
|
0 commit comments