ローカルで時間計測しながらテストする
Twitterで質問されたので記事にします。
宣伝
毎日C D問題通知Botの運営を@tettyあさんとしています。
毎日C/D問題、やってみませんか???
概要
今回の目標はなるべく簡単に時間を計測することです。
前提として、以前の入茶記事のような構成で、AtCoder/内にprobrem.exeが生成されていることが必要です。
今回はlinuxのビルトイン機能であるtimeコマンドを使用しました。
注意事項として、私は専門家でもなんでもないので、初心者ががんばって書いたきたないコードが出てきます。
温かい目で見守ってください。
あと、よくわからなかったのでごり押しの側面が強いです。ご了承ください。
本編
ファイル構成
本質でないところは省略します(入茶記事を参照してください)
AtCoder/
├ (略)
├ sh
│ ├ Runtime.txt
│ ├ test-time.exe
│ ├ test.sh
│ └ (output.cpp)
├ probrem.exe
├ (略)
Runtime.txt
ただのバッファファイルです。自分ではどうあがいても使わずに目標を達成できませんでした。
ファイル名は適当です。
ちなみにファイルは作らなくていいです。
test.sh
メイン処理のファイルになります。
一番苦戦しました。
まずはコードです。ユーザー名はAtCoderフォルダでpwdとするとわかりやすいと思います。
#! /bin/bash
TIMEFORMAT=$'!!time!!\n%3R\n%3U'
cd /home/(ユーザー名)/AtCoder/sh
(echo -e "$(time ../problem.exe 2>./Runtime.txt|| sed -i "1iExit Status:$?" ./Runtime.txt)") 2>>./Runtime.txt
./test-time.exe < ./Runtime.txt
簡単に解説すると、TIMEFORMATで表記を変更しておきます。
統一して、被らないものであれば、これである必要はありません。
次にファイルのあるフォルダに移動します。移動するのはその後の処理は簡潔に記述するためです。
そして、ここでコマンドを実行します。この時、Runtime.txtにいろいろ出力されます。
最後に、test-time.exe(後述)を実行します。
【一部修正】
コマンドの一部に誤りがありました。(自分でも実行して気づきました…)
(echo -e "←これ (略) Runtime.txt) これ→ ")
ダブルクオーテーションが抜けていました…申し訳ありません…
test-time.exe(output.cpp)
過去の自分ががんばって作ったものです。
boostライブラリを使用しているので、場合によってはインストールしてください。
出力形式は@Apiros3さんのものを参考にさせてもらいました。
//output.cpp
#include <boost/format.hpp>
#include <iomanip>
#include <iostream>
#include <regex>
#include <vector>
#define BGY "\x1b[43m"
#define BGR "\x1b[46m"
#define AC "\x1b[32m"
#define D "\x1b[49m"
#define BK "\x1b[30m"
#define YELLOW "\x1b[33m"
#define RED "\x1b[31m"
#define DEFAULT "\x1b[39m"
using ll = long long;
int main() {
std::string inputs;
std::vector<std::string> Ss;
int count = 0;
do {
count++;
getline(std::cin, inputs);
if (inputs != "!!time!!") Ss.push_back(inputs);
} while (inputs != "!!time!!");
long double real, user;
std::cin >> real >> user;
if (count != 1) {
std::cout << (" " BK BGR "************ RE ************" DEFAULT D "\n");
}
if (user >= 2.000)
std::cout << (" " BGY "************ TLE ************" DEFAULT D "\n");
else if (count == 1)
std::cout << ("\t " AC "PROGRAM SUCCESSFUL :)" DEFAULT D "\n");
std::string printer =
"\
+---------------------------+\n\
| * SYSTEM: t = %8lld ms |\n\
| * INPUT : t = %8lld ms |\n\
+---------------------------+\n\
";
std::cout << boost::format(printer) % ll(real * 1000) % ll(user * 1000);
if (count != 1) {
std::cout << "Detail...:" << std::endl;
std::cout << RED << Ss[0] << DEFAULT << std::endl;
for (int i = 1; i < int(Ss.size()); i++) {
std::cout << Ss[i] << std::endl;
}
}
}
作りはそこそこ適当です。
output.cppとして保存し、AtCoder/sh内で
$ g++ output.cpp -o test-time.exe
を実行してコンパイルします。
名前は統一すればなんでもいいです。
alias
今回はせっかくなので、.bashrcに追記する方法でいきます。
$ echo -e "alias test=/home/(ユーザー名)/sh/test.sh" >>~/.bashrc
$ source ~/.bashrc
これを実行することで、.bashrcにエイリアスが追加され、
$ test
でテストをすることができるようになります。
まとめ
今回は入茶記事の続き(?)としてtestコマンドでテストを実行する方法を紹介しました。
私も初心者なので至らない点も多かったと思います…
何かわからないことがあればTwitterのリプでもDMでもいいので、気軽に聞いてください!