From 676da10a45af912d9226dce4cb447bf7bd923da0 Mon Sep 17 00:00:00 2001 From: Li Jin Date: Fri, 24 Jul 2026 17:12:21 +0800 Subject: Optimize compiler parsing and module state --- src/yue.cpp | 132 +++++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 105 insertions(+), 27 deletions(-) (limited to 'src/yue.cpp') diff --git a/src/yue.cpp b/src/yue.cpp index 4bb4e70..8fe2aba 100644 --- a/src/yue.cpp +++ b/src/yue.cpp @@ -9,18 +9,25 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #include "yuescript/yue_compiler.h" #include "yuescript/yue_parser.h" +#include #include +#include #include +#include #include +#include #include #include #include #include #include +#include #include +#include #include #include #include +#include using namespace std::string_view_literals; using namespace std::string_literals; using namespace std::chrono_literals; @@ -32,35 +39,102 @@ using namespace std::chrono_literals; #if __has_include() #include -template -std::future async(const std::function& f) { - using Fn = std::packaged_task; - auto task = new Fn(f); - std::future fut = task->get_future(); +#endif - pthread_attr_t attr; - pthread_attr_init(&attr); - pthread_attr_setstacksize(&attr, 8 * 1024 * 1024); +class AsyncPool { +public: + explicit AsyncPool(size_t workerCount) { + workerCount = std::max(workerCount, 1); +#if __has_include() + pthread_attr_t attr; + pthread_attr_init(&attr); + pthread_attr_setstacksize(&attr, 8 * 1024 * 1024); + _workers.reserve(workerCount); + for (size_t i = 0; i < workerCount; i++) { + pthread_t worker; + const int result = pthread_create(&worker, &attr, [](void* data) -> void* { + static_cast(data)->run(); + return nullptr; + }, this); + if (result != 0) { + { + std::lock_guard lock(_mutex); + _stopping = true; + } + _condition.notify_all(); + for (auto createdWorker : _workers) { + pthread_join(createdWorker, nullptr); + } + pthread_attr_destroy(&attr); + throw std::runtime_error("failed to create compiler worker thread"); + } + _workers.push_back(worker); + } + pthread_attr_destroy(&attr); +#else + _workers.reserve(workerCount); + for (size_t i = 0; i < workerCount; i++) { + _workers.emplace_back([this]() { run(); }); + } +#endif + } - pthread_t th; - pthread_create(&th, &attr, - [](void* p)->void* { - std::unique_ptr fn(static_cast(p)); - (*fn)(); - return nullptr; - }, - task); - pthread_attr_destroy(&attr); - pthread_detach(th); - return fut; -} + ~AsyncPool() { + { + std::lock_guard lock(_mutex); + _stopping = true; + } + _condition.notify_all(); +#if __has_include() + for (auto worker : _workers) { + pthread_join(worker, nullptr); + } #else -template -std::future async(const std::function& f) { - // fallback: ignore stack size - return std::async(std::launch::async, f); -} + for (auto& worker : _workers) { + worker.join(); + } #endif + } + + template + std::future async(const std::function& f) { + auto task = std::make_shared>(f); + auto result = task->get_future(); + { + std::lock_guard lock(_mutex); + _tasks.emplace_back([task]() { (*task)(); }); + } + _condition.notify_one(); + return result; + } + +private: + void run() { + while (true) { + std::function task; + { + std::unique_lock lock(_mutex); + _condition.wait(lock, [this]() { + return _stopping || !_tasks.empty(); + }); + if (_stopping && _tasks.empty()) return; + task = std::move(_tasks.front()); + _tasks.pop_front(); + } + task(); + } + } + + std::mutex _mutex; + std::condition_variable _condition; + std::deque> _tasks; + bool _stopping = false; +#if __has_include() + std::vector _workers; +#else + std::vector _workers; +#endif +}; #if not(defined YUE_NO_MACRO && defined YUE_COMPILER_ONLY) #define _DEFER(code, line) std::shared_ptr _defer_##line(nullptr, [&](auto) { \ @@ -823,6 +897,10 @@ int main(int narg, const char** args) { } } #endif // YUE_COMPILER_ONLY + const size_t workerCount = std::min( + files.size(), + static_cast(std::max(1u, std::thread::hardware_concurrency()))); + AsyncPool pool(workerCount); #ifndef YUE_NO_WATCHER if (watchFiles) { auto fullWorkPath = fs::absolute(fs::path(workPath)).string(); @@ -832,7 +910,7 @@ int main(int narg, const char** args) { } std::list> results; for (const auto& file : files) { - auto task = async([=]() { + auto task = pool.async([=]() { #ifndef YUE_COMPILER_ONLY return compileFile(fs::absolute(file.first), config, fullWorkPath, fullTargetPath, minify, rewrite); #else @@ -870,7 +948,7 @@ int main(int narg, const char** args) { #endif // YUE_NO_WATCHER std::list>> results; for (const auto& file : files) { - auto task = async>([=]() { + auto task = pool.async>([=]() { std::ifstream input(file.first, std::ios::in); if (input) { std::string s( -- cgit v1.2.3-55-g6feb