coost README

The project's README from github.com/idealvin/coost. As one markdown file: README.md.

coost

简体中文 | English
Linux Mac Windows Windows-arm64 FreeBSD Release License: MIT

A tasteful, minimal C++ base library.

Introduction

coost is a lightweight, high-performance, easy-to-use C++ base library. It supports Linux, macOS, Windows, FreeBSD, and CPU architectures such as x86, x64, ARM, and ARM64.

coost, abbreviated as co, includes go-style coroutines, networking, logging, config parsing, unit testing, benchmarking, memory allocator, and other components. Its goal is to make C++ programming simple and enjoyable.

Commercial Support

coost remains open source. If you use coost in production and need in-depth support such as custom development, architecture adaptation (RISC-V / MIPS), coroutine hooks, performance optimization, or team training, the author offers paid commercial support to reduce risk and save time.

For service packages, pricing, and process, see:

👉 coost Commercial Support

Contact the author via GitHub Issues or email [email protected]. A free initial diagnosis is available to assess scope and feasibility.

Documentation

The documentation currently lags behind the latest version of coost. Please refer to the latest code and the include/co headers for the most accurate information.

Core Components

flag

flag is a command-line argument and config file parsing library. It supports flag aliases, automatic config file generation, and more.

#include "co/flag.h"
#include "co/print.h"

DEF_bool(x, false, "Comment here");
DEF_int32(n, 0, "Comment here");
DEF_string(s, "hello world", "Comment here");

int main(int argc, char** argv) {
    flag::parse(argc, argv);
    co::println("x: ", FLG_x);
    co::println("n: ", FLG_n);
    co::println("s: ", FLG_s);
    return 0;
}

Coroutines

coost implements a coroutine mechanism similar to goroutine in Golang. It has the following features:

#include "co/co.h"
#include "co/flag.h"
#include "co/print.h"

int main(int argc, char** argv) {
    flag::parse(argc, argv);

    co::wait_group wg(2);

    go([wg](){
        co::println("hello world");
        wg.done();
    });

    go([wg](){
        co::println("hello again");
        wg.done();
    });

    wg.wait();
    return 0;
}

Networking

coost provides a coroutine-based network programming framework:

Logging

log is a high-performance logging component. It supports printing stack traces when the program crashes.

#include "co/log.h"

int main(int argc, char** argv) {
    flag::parse(argc, argv);
    log::info("hello ", 23);   // info
    log::warn("hello ", 23);   // warning
    log::error("hello ", 23);  // error
    log::check(1+1==2, "xx");  // runtime assertion; prints stack trace and exits on failure
    return 0;
}

log is very fast. Here are some test results:

platform glog co/log speedup
win2012 HDD 1.6MB/s 180MB/s 112.5
win10 SSD 3.7MB/s 560MB/s 151.3
mac SSD 17MB/s 450MB/s 26.4
linux SSD 54MB/s 1023MB/s 18.9

The table above shows the write speed comparison between co/log and glog when continuously printing 1 million logs in a single thread. co/log is nearly two orders of magnitude faster than glog.

threads linux co/log linux spdlog win co/log win spdlog speedup
1 0.087235 2.076172 0.117704 0.461156 23.8/3.9
2 0.183160 3.729386 0.158122 0.511769 20.3/3.2
4 0.206712 4.764238 0.316607 0.743227 23.0/2.3
8 0.302088 3.963644 0.406025 1.417387 13.1/3.5

The table above shows the time consumed to print 1 million logs with 1, 2, 4, and 8 threads respectively, in seconds. speedup is the performance improvement factor of co/log over spdlog on Linux and Windows.

Unit Testing

unitest is a simple and easy-to-use unit testing framework. Many components in coost use it to write unit test code, providing important assurance for coost's stability.

#include "co/unitest.h"
#include "co/os.h"

DEF_test(os) {
    DEF_case(homedir) {
        EXPECT_NE(os::homedir(), "");
    }

    DEF_case(cpunum) {
        EXPECT_GT(os::cpunum(), 0);
    }
}

int main(int argc, char** argv) {
    flag::parse(argc, argv);
    co::run_unitests();
    return 0;
}

The above is a simple example. The DEF_test macro defines a test unit, which is actually a function. The DEF_case macro defines a test case, and each test case is actually a code block.

The coost/unitest directory contains the unit test code in coost. Run the following commands to build and run:

xmake b unitest
xmake r unitest      # run all unit test cases
xmake r unitest -os  # run only test cases in the os unit; os is the unit test name

Benchmark

benchmark is a simple and easy-to-use performance benchmark framework.

#include "co/benchmark.h"
#include "co/atomic.h"

BM_group(atomic) {
    int i = 0;

    BM_add(atomic_inc) {
        co::atomic_inc(&i);
    }
    BM_use(i);

    BM_add(atomic_dec) {
        co::atomic_dec(&i);
    }
    BM_use(i);
}

The coost/benchmark directory contains some performance test code. Run the following commands to build and run:

xmake b benchmark
xmake r benchmark        # run all benchmark code by default
xmake r benchmark -mem   # run only benchmark code in BM_group(mem)

JSON

JSON adopts a fluent interface design, making it easier to use.

// {"a":23,"b":false,"s":"123","v":[1,2,3],"o":{"xx":0}}
json::any x = {
    { "a", 23 },
    { "b", false },
    { "s", "123" },
    { "v", {1,2,3} },
    { "o", {
        {"xx", 0}
    }},
};

// equal to x
json::any y = Json()
    .add_member("a", 23)
    .add_member("b", false)
    .add_member("s", "123")
    .add_member("v", Json().push_back(1).push_back(2).push_back(3))
    .add_member("o", Json().add_member("xx", 0));

x.get("a").as_int();       // 23
x.get("s").as_string();    // "123"
x.get("s").as_int();       // 123, string -> int
x.get("v", 0).as_int();    // 1
x.get("v", 2).as_int();    // 3
x.get("o", "xx").as_int(); // 0

Below is the performance comparison between co/json and rapidjson:

os co/json stringify co/json parse rapidjson stringify rapidjson parse speedup
win 569 924 2089 2495 3.6/2.7
mac 783 1097 1289 1658 1.6/1.5
linux 468 764 1359 1070 2.9/1.4

The table above shows the average time for stringify and parse measured after minifying twitter.json, in microseconds (us). speedup is the performance improvement factor of co/json over rapidjson in stringify and parse.

Code Structure

Build

Compiler Requirements

The latest version of coost requires a compiler that supports C++17:

Build with xmake

coost recommends xmake as the build tool.

Quick Start

# All commands are executed in the coost root directory, and this will not be repeated below
xmake       # build libco by default
xmake -a    # build all projects (libco, benchmark, gen, test, unitest)

Enable backtrace

On Linux and macOS, printing stack traces on crashes requires libbacktrace. Newer versions of gcc on Linux already have a built-in backtrace library; on macOS it usually needs to be installed manually.

xmake f --with_backtrace=true
xmake b stack   # test/stack.cc
xmake r stack   # run stack test program

Install libco

xmake install -o pkg          # package and install to the pkg directory
xmake i -o pkg                # same as above
xmake install -o /usr/local   # install to /usr/local

Build with cmake

Build libco

mkdir cmakebuild && cd cmakebuild
cmake ..
make -j8

Build all projects

mkdir cmakebuild && cd cmakebuild
cmake .. -DBUILD_ALL=ON -DCMAKE_INSTALL_PREFIX=/usr/local
make -j8
cd bin
./unitest  # run unit test program

Enable backtrace

mkdir cmakebuild && cd cmakebuild
cmake .. -DWITH_BACKTRACE=ON
make -j8

License

The MIT license. coost includes code from some other projects, which may use different licenses. See LICENSE.md for details.

Special Thanks

coost (idealvin/coost)

Searching Database…

4.2K ·GitHub
这是干什么的?coost(又名 co)是一个轻量、高性能、易用的 C++ 基础库,它宣称的目标是让 C++ 编程变得简单又愉快。
这个库里都有什么?它是一个基础库(编译产物为 libco),不是应用程序:里面包含 go 风格的协程、网络、日志、配置解析、单元测试、性能测试、内存分配器以及 JSON 组件。
怎么构建?需要什么编译器?你需要一个支持 C++17 的编译器(gcc、clang 或 MSVC)。作者推荐用 xmake 构建,也提供了 cmake 的构建方式,构建结果安装为 libco。
文档写得怎么样?不算完整——文档目前落后于最新版本,所以代码和 include/co 里的头文件才是最准确的参考。
它能在 Linux、macOS 和 Windows 上运行吗?可以——它支持 Linux、macOS、Windows 和 FreeBSD,CPU 架构覆盖 x86、x64、ARM 和 ARM64。
我能在商业项目里用它吗?可以,它采用 MIT 许可证,但 coost 中包含了来自其他项目的代码,这些代码可能使用不同的许可证,所以请查看 LICENSE.md。作者还提供可选的付费商业支持。
它的单元测试框架是怎么用的?unitest 组件通过宏来使用:DEFtest 定义一个测试单元,本质上就是一个函数;DEFcase 定义一个测试用例,本质上是一段代码块。coost 自己的组件就是用它来测试的,还有一个按同样方式构建的独立性能测试框架。
作者为什么要做这个项目?它的目标就是让 C++ 编程变得简单又愉快——打造一个精致、精简的基础库,把协程、网络、日志、JSON 和测试工具都收进一个依赖里。
What are similar projects?mars, zenc, spdlog, muduo, fasthttp, mimalloc, conc, capnproto
Creator
idealvin
Size
3.7 MB
Stars
4.2K
Age
6y
Commits · 90 Days