blog.bouzuya.net

2023-01-10 Rust での Docker イメージのサイズの削減 / ABC049 A, B, C, D を解いた

2022-07-25 に rust-musl-builder (https://github.com/emk/rust-musl-builder) の使用について書いた。 Rust を使った Docker イメージのサイズの削減のために rust-musl-builder を使った。

しかし ekidd/rust-musl-builder の Docker イメージはもう更新されていない (2022-11-25) ので避けたほうが良い。そもコンパイルが通らないこともある。 https://github.com/emk/rust-musl-builder/issues/147

代替手段は必要なライブラリを入れた上で cargo build などのオプションに --target=x86_64-unknown-linux-musl を指定すれば良い。これは rust-musl-builder でやっていたことを自分でやっているだけではある。

bouzuya/rust-sandbox で言うと date-to-week-date, genuuid, twiq, twiq-light あたりでこの方法を使っている。 genuuid の場合は↓のような感じ。 musl-dev を入れておかないとたぶんビルドできない。

FROM rust:1.66-alpine as builder

WORKDIR /usr/src/genuuid
RUN apk update && apk add --no-cache musl-dev
COPY ./Cargo.lock ./Cargo.lock
COPY ./Cargo.toml ./Cargo.toml
RUN mkdir src/
RUN touch src/lib.rs
RUN cargo build --release --target=x86_64-unknown-linux-musl
COPY . .
RUN cargo install --path . --target=x86_64-unknown-linux-musl

FROM scratch
ENV PORT=8080
COPY --from=builder /usr/local/cargo/bin/genuuid /usr/local/bin/genuuid
ENTRYPOINT ["genuuid"]

genuuid は 7.02MB 。以前は 86MB だったのでぼちぼちのサイズになっている。

$ docker pull ghcr.io/bouzuya/rust-sandbox/genuuid:0.4.2
# ...

$ docker image list genuuid
REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
genuuid      0.4.2     761d70ce66ac   56 minutes ago   7.02MB

ABC049 : AtCoder Beginner Contest 049 の A, B, C, D を解いた。

use std::collections::{HashMap, VecDeque};

use proconio::{input, marker::Usize1};

fn adjacency_list(n: usize, uv: &[(usize, usize)]) -> Vec<Vec<usize>> {
    let mut e = vec![vec![]; n];
    for (u, v) in uv.iter().copied() {
        e[u].push(v);
        e[v].push(u);
    }
    e
}

fn bfs(n: usize, edges: &[Vec<usize>]) -> Vec<usize> {
    let mut color = 0_usize;
    let mut colors = vec![n; n];
    for start in 0..n {
        if colors[start] == n {
            let mut deque = VecDeque::new();
            deque.push_back(start);
            colors[start] = color;
            while let Some(u) = deque.pop_front() {
                for v in edges[u].iter().copied() {
                    if colors[v] == n {
                        colors[v] = color;
                        deque.push_back(v);
                    }
                }
            }
            color += 1;
        }
    }
    colors
}

fn main() {
    input! {
        n: usize,
        k: usize,
        l: usize,
        pq: [(Usize1, Usize1); k],
        rs: [(Usize1, Usize1); l],
    };

    let e1 = adjacency_list(n, &pq);
    let e2 = adjacency_list(n, &rs);

    let c1 = bfs(n, &e1);
    let c2 = bfs(n, &e2);

    let mut count = HashMap::new();
    for zipped in c1.iter().copied().zip(c2.iter().copied()) {
        *count.entry(zipped).or_insert(0) += 1;
    }

    for zipped in c1.iter().copied().zip(c2.iter().copied()) {
        println!("{}", count.get(&zipped).unwrap());
    }
}

今日のコミット。