LoginSignup
2
0

More than 1 year has passed since last update.

cargo-profiler を Mac で使う

Posted at

AtCoderのマラソンコンテストに際して、Rustコードのプロファイルを cargo-profiler を使用して取ろうとしたのですが、

NOTE: This subcommand can only be used on Linux machines.

とある通りLinuxにしか対応していなかったので、Docker経由で使用しました。

その手順を書きます。

手順

Dockerイメージのビルド

$ docker build -t cargo-profiler .

コマンドを、下記の Dockerfile を設置したディレクトリで実行する。

Dockerfile
# cf. https://github.com/rust-lang/docker-rust/blob/a035f6fa1f14754bab8f34376c386fafc831b652/1.49.0/buster/Dockerfile

FROM buildpack-deps:buster

ENV RUSTUP_HOME=/usr/local/rustup \
    CARGO_HOME=/usr/local/cargo \
    PATH=/usr/local/cargo/bin:$PATH \
    RUST_VERSION=1.49.0

RUN set -eux; \
    dpkgArch="$(dpkg --print-architecture)"; \
    case "${dpkgArch##*-}" in \
        amd64) rustArch='x86_64-unknown-linux-gnu'; rustupSha256='ed7773edaf1d289656bdec2aacad12413b38ad0193fff54b2231f5140a4b07c5' ;; \
        armhf) rustArch='armv7-unknown-linux-gnueabihf'; rustupSha256='7a7b9d246ad63358705d8d4a7d5c2ef1adfec24525d1d5c44a7739e1b867e84d' ;; \
        arm64) rustArch='aarch64-unknown-linux-gnu'; rustupSha256='f80a0a792b3ab905ab4919474daf4d3f60e574fc6987e69bfba2fd877241a8de' ;; \
        i386) rustArch='i686-unknown-linux-gnu'; rustupSha256='4473c18286aa1831683a772706d9a5c98b87a61cc014d38063e00a63a480afef' ;; \
        *) echo >&2 "unsupported architecture: ${dpkgArch}"; exit 1 ;; \
    esac; \
    url="https://static.rust-lang.org/rustup/archive/1.23.1/${rustArch}/rustup-init"; \
    wget "$url"; \
    echo "${rustupSha256} *rustup-init" | sha256sum -c -; \
    chmod +x rustup-init; \
    ./rustup-init -y --no-modify-path --profile minimal --default-toolchain $RUST_VERSION --default-host ${rustArch}; \
    rm rustup-init; \
    chmod -R a+w $RUSTUP_HOME; \
    rustup --version; \
    cargo --version; \
    rustc --version;

RUN apt-get update \
    && apt-get install -y valgrind

RUN cargo install cargo-profiler \
    && chmod -R a+w $CARGO_HOME

(このファイルは、https://github.com/rust-lang/docker-rust/blob/a035f6fa1f14754bab8f34376c386fafc831b652/1.49.0/buster/Dockerfile の末尾に

RUN apt-get update \
    && apt-get install -y valgrind

RUN cargo install cargo-profiler \
    && chmod -R a+w $CARGO_HOME

を書き加えたものになります。

AtCoderのジャッジサーバのバージョンに合わせて、Rust v1.49.0を使っています。)

cargoプロジェクトのビルド

$ docker run --rm --user "$(id -u)":"$(id -g)" \
    -v /your/cargo/project/path:/workspace \
    -w /workspace cargo-profiler \
    cargo build --release

/your/cargo/project/path には、プロファイル対象のcargoプロジェクトのルートディレクトリを記載してください。)

プロファイル実行

$ docker run --rm --user "$(id -u)":"$(id -g)" \
    -v /your/cargo/project/path:/workspace \
    -w /workspace cargo-profiler \
    cargo profiler callgrind --bin target/release/a -n 5

(target/release/a 部分は実行ファイルパスを入れてください。)

以下のような結果が得られます。

Profiling a with callgrind...

Total Instructions...7,131,502,099

1,228,544,445 (17.2%) ???:a::State
-----------------------------------------------------------------------
1,067,368,888 (15.0%) malloc.c:_int_free'2
-----------------------------------------------------------------------
1,017,529,165 (14.3%) ???:<alloc::vec
-----------------------------------------------------------------------
675,019,392 (9.5%) ???:a::State
-----------------------------------------------------------------------
462,097,916 (6.5%) malloc.c:_int_malloc'2
-----------------------------------------------------------------------

callgrind の他に、cachegrind というコマンドもあるようです(私は使ったことないです)。

余談

  • Macでも使えたという記事も見つけたのですが、私の環境下では動きませんでした。OSバージョンとかによるんですかね?1
  • macos-profiler という MacOS 向けの Rustプロファイラもありましたが、私は動かせませんでした。最終コミットが'19年5月だったので、私の環境だと非対応って話な気がしてます。
  • 標準入力が渡せないっぽいので、競プロ用途だとちょっと手間2だったりします。私は cargo-profiler を使うときだけ、コードを入力をファイルから読み込むように書き換えて使っています。

  1. 私の環境は Apple M1, Big Sur って感じです。 

  2. 競技プログラミングコンテストは、入力を標準入力から受け取る形式が多いため 

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0