見出し画像

ローカルで時間計測しながらテストする

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でもいいので、気軽に聞いてください!



いいなと思ったら応援しよう!