Symfoware

Symfowareについての考察blog

Nim デバッグビルドとリリースビルドの実行速度

Nimで郵便番号と住所をデータベースに登録するプログラムを作ってみました。
Nim トランザクションを使用し、郵便番号と住所情報をMySQLに登録する

ふと、デバッグビルドとリリースビルドで実行速度が違うのか気になったので調べてみます。
また、参考として同様のPythonプログラムの実行速度も見てみます。

Python



PythonからMySQLへの接続はmysql-connector-python-rfを使用しました。
プログラムはこんな感じになりました。


  1. import codecs
  2. import mysql.connector
  3. def mystrip(s):
  4.     return s.strip('"')
  5. con = mysql.connector.connect(
  6.     host = 'localhost',
  7.     port = 3306,
  8.     user = 'admin',
  9.     password = 'P@ssw0rd',
  10.     database = 'sample',
  11. )
  12. con.autocommit = False
  13. cur = con.cursor()
  14. zipcodeSet = set()
  15. with codecs.open('KEN_ALL.CSV', 'r', 'CP932') as f:
  16.     for line in f:
  17.         # カンマで分割
  18.         data = line.strip().split(',')
  19.         # 2番目:郵便番号
  20.         zipcode = mystrip(data[2])
  21.         # 6,7,8番目:住所
  22.         address = mystrip(data[6]) + mystrip(data[7]) + mystrip(data[8])
  23.         # 郵便番号の重複チェック
  24.         if zipcode in zipcodeSet:
  25.             print("skip " + zipcode)
  26.             continue
  27.         zipcodeSet.add(zipcode)
  28.         # 登録実行
  29.         cur.execute("INSERT INTO post (zip_code, address) VALUES (%s, %s)", (zipcode, address))
  30. con.commit()
  31. cur.close()
  32. con.close()







実測



データベースへの登録が最も時間がかかりそうなので、
あまり差がでないかもしれませんがテストしてみます。

Nimのバージョンは0.18.0。
Pythonのバージョンは3.6.5です。

デバッグビルドでコンパイル。


$ nim c sample.nim



timeコマンドで時間を計測します。


$ time ./sample
real    0m22.027s
user    0m4.703s
sys    0m1.706s




次にリリースビルド。


$ nim c -d:release sample.nim
$ time ./sample
real    0m18.933s
user    0m1.613s
sys    0m1.557s



ちゃんと高速になりましたね。
※3回測定しましたが、概ね同様の実行時間でした。

最後にPython。


$ time python3 comp.py
real    0m33.222s
user    0m10.633s
sys    0m3.123s




データベースへの登録処理なんで差は出ないだろうと思っていましたが、
Nimで書くと高速に処理されますね。
関連記事

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2018/08/27(月) 23:32:12|
  2. nim
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集

Nim トランザクションを使用し、郵便番号と住所情報をMySQLに登録する

読み仮名データの促音・拗音を小書きで表記するもの(zip形式)
NimでこちらのデータをMySQLに登録してみようと思います。

ファイルの読み込みと重複排除



ファイルの読み込みや郵便番号の重複チェックはこちら。
Nim 文字コードを指定したファイルの読み書き
Nim 文字列の結合、分割とトリム(strutils, split, strip)
Nim HashSetの使い方


データベース接続と登録



データベースへの接続、登録はこちら。
Nim MySQLに文字コードを指定して接続し、データの検索、登録を行う(db_mysql)

登録用にこんなテーブルを用意しておきました。


  1. CREATE TABLE post (
  2. zip_code CHAR(7) NOT NULL PRIMARY KEY,
  3. address VARCHAR(255) NOT NULL
  4. );





サンプル



試行錯誤の末のサンプルはこんな感じになりました。


  1. import strutils
  2. import encodings
  3. import sets
  4. import db_mysql
  5. proc mystrip(s: string):string =
  6.     return strip(s, chars={'"'})
  7. proc main() =
  8.     let enc = encodings.open("UTF-8", "CP932")
  9.     let f : File = open("KEN_ALL.CSV" ,FileMode.fmRead)
  10.     let db = open("localhost", "root", "P@ssw0rd", "sample")
  11.     discard setEncoding(db, "utf8mb4")
  12.     
  13.     defer:
  14.         close(enc)
  15.         close(f)
  16.         db.close()
  17.     var zipcodeSet = initSet[string]()
  18.     while not f.endOfFile:
  19.         # 1行読み込み
  20.         let line = enc.convert(f.readLine)
  21.         # カンマで分割
  22.         let data = split(line, ',')
  23.         # 2番目:郵便番号
  24.         let zipcode = mystrip(data[2])
  25.         # 6,7,8番目:住所
  26.         let address = mystrip(data[6]) & mystrip(data[7]) & mystrip(data[8])
  27.         # 郵便番号の重複チェック
  28.         if zipcode in zipcodeSet:
  29.             echo "skip " & zipcode
  30.             continue
  31.         zipcodeSet.incl(zipcode)
  32.         # 登録実行
  33.         db.exec(sql"INSERT INTO post (zip_code, address) VALUES (?, ?)", zipcode, address)
  34. main()



このプログラムを動かしてみましたが、びっくりするほど遅いです。
途中で実行を停止しました。



トランザクション



ちゃんとトランザクションをかけるように修正します。


  1. import strutils
  2. import encodings
  3. import sets
  4. import db_mysql
  5. proc mystrip(s: string):string =
  6.     return strip(s, chars={'"'})
  7. proc main() =
  8.     let enc = encodings.open("UTF-8", "CP932")
  9.     let f : File = open("KEN_ALL.CSV" ,FileMode.fmRead)
  10.     # データベースに接続し文字コードをセット
  11.     let db = open("localhost", "root", "P@ssw0rd", "sample")
  12.     discard setEncoding(db, "utf8mb4")
  13.     # トランザクション開始
  14.     db.exec(sql"START TRANSACTION")
  15.     defer:
  16.         close(enc)
  17.         close(f)
  18.         db.close()
  19.     var zipcodeSet = initSet[string]()
  20.     while not f.endOfFile:
  21.         # 1行読み込み
  22.         let line = enc.convert(f.readLine)
  23.         # カンマで分割
  24.         let data = split(line, ',')
  25.         # 2番目:郵便番号
  26.         let zipcode = mystrip(data[2])
  27.         # 6,7,8番目:住所
  28.         let address = mystrip(data[6]) & mystrip(data[7]) & mystrip(data[8])
  29.         # 郵便番号の重複チェック
  30.         if zipcode in zipcodeSet:
  31.             echo "skip " & zipcode
  32.             continue
  33.         zipcodeSet.incl(zipcode)
  34.         # 登録実行
  35.         db.exec(sql"INSERT INTO post (zip_code, address) VALUES (?, ?)", zipcode, address)
  36.     db.exec(sql"COMMIT")
  37. main()



これで現実的な速度でプログラムが終了するようになりました。
関連記事

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2018/08/27(月) 22:55:44|
  2. nim
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集

Nim HashSetの使い方

Nimで重複を許さないHashSetの使い方メモです。

sets



こちらが参考になります。
Module sets

「initSet」で初期化済みのHashSetを生成。
「incl」で値を追加します。


  1. import sets
  2. var values = initSet[int]()
  3. values.incl(2)
  4. values.incl(4)
  5. values.incl(6)
  6. values.incl(2)
  7. echo values.len
  8. echo "----------------"
  9. for value in values:
  10.     echo value




実行結果


$ nim c -r sample.nim
3
----------------
2
4
6





リストからHashSetへの変換(toSet)



toSetでリストからHashSetを生成できます。


  1. import sets
  2. var values = toSet([2, 4, 6])
  3. values.incl(2)
  4. echo values.len
  5. echo "----------------"
  6. for value in values:
  7.     echo value





値の削除(excl)



追加した値を削除するには「excl」を使用します。


  1. import sets
  2. var values = toSet([2, 4, 6])
  3. values.excl(2)
  4. echo values.len
  5. echo "----------------"
  6. for value in values:
  7.     echo value




実行結果


$ nim c -r sample.nim
2
----------------
4
6






値の存在チェック(contains)



HashSetの中に指定した値が存在するかチェックするには「contains」を使用します。


  1. import sets
  2. var values = toSet([2, 4, 6])
  3. echo values.contains(2)
  4. echo values.contains(3)




実行結果


$ nim c -r sample.nim
true
false

関連記事

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2018/08/27(月) 22:21:07|
  2. nim
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集

Snipe-IT を Ubuntu Server 18.04にインストール

IT資産管理ツールの「Snipe-IT」
Ubuntu Server 18.04にインストールしてみます。

Ubuntu Server 18.04
Nginx
MySQL 5.7
php-fpm 7.2

という環境です。


必要なソフト



事前にnginxやphp、MySQLをインストールしておきます。
nginxはextrasじゃなくてもOKです。


$ sudo apt install nginx-extras
$ sudo apt install mysql-server
$ sudo apt install php7.2-fpm php-gd php-mbstring php-curl php-dom php-mysql





ダウンロード



インストール手順はこちらを参考にしました。
https://snipe-it.readme.io/docs/downloading#section-3-download-the-installer

Git Cloneでの資産取得が推奨されているので従います。


$ cd /var/www
$ sudo git clone https://github.com/snipe/snipe-it



ユーザーを変更しておきます。


$ sudo chown -R `whoami`:`whoami` ./snipe-it






設定



続いてConfigurationです。
https://snipe-it.readme.io/docs/configuration

チェックアウトしたディレクトリに移動。
サンプルの設定ファイルをコピーします。


$ cd snipe-it/
$ cp .env.example .env



コピーした設定ファイルを編集。


$ vi .env



最低限変更が必要な箇所はタイムゾーンとデータベースの接続設定です。
環境に合わせて変更します。


# --------------------------------------------
# REQUIRED: BASIC APP SETTINGS
# --------------------------------------------
APP_ENV=production
APP_DEBUG=false
APP_KEY=ChangeMe
APP_URL=null
APP_TIMEZONE='Asia/Tokyo'
APP_LOCALE=ja


# --------------------------------------------
# REQUIRED: DATABASE SETTINGS
# --------------------------------------------
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_DATABASE=snipeit
DB_USERNAME=admin
DB_PASSWORD=P@ssw0rd
DB_PREFIX=null
DB_DUMP_PATH='/usr/bin'
DB_CHARSET=utf8mb4
DB_COLLATION=utf8mb4_unicode_ci







依存しているライブラリのインストール



依存しているライブラリのインストールを行います。
https://snipe-it.readme.io/docs/install-dependencies


$ curl -sS https://getcomposer.org/installer | php
$ php composer.phar install --no-dev --prefer-source



エラーが発生しました。

Loading composer repositories with package information
Installing dependencies from lock file
Warning: The lock file is not up to date with the latest changes in composer.json. You may be getting outdated dependencies. Run update to update them.
Your requirements could not be resolved to an installable set of packages.



ロックファイルを削除してリトライ。


$ rm -f composer.lock
$ php composer.phar install --no-dev --prefer-source



またエラーが発生しました。

Loading composer repositories with package information
Updating dependencies
Your requirements could not be resolved to an installable set of packages.

Problem 1
    - Installation request for laravel/framework 5.4.35 -> satisfiable by laravel/framework[v5.4.35].
    - roave/security-advisories dev-master conflicts with laravel/framework[v5.4.35].
    - Installation request for roave/security-advisories dev-master -> satisfiable by roave/security-advisories[dev-master].




解決はこちらが参考になります。
Composer Security Conflict security-advisories with laravel 5.4.35

composer.jsonからroave/security-advisoriesを削除します。


$ vi composer.json



44行目の指定を削除。


- "roave/security-advisories": "dev-master",



リトライ


$ php composer.phar install --no-dev --prefer-source



これでインストールできました。




初期設定とパーミッション



API Keyを作成します。


$ php artisan key:generate
**************************************
*     Application In Production!     *
**************************************

Do you really wish to run this command? (yes/no) [no]:
> yes




ディレクトリのパーミッションを変更しておきます。


$ chmod -R 777 storage
$ chmod -R 777 public/uploads





データベースの準備



データベースにユーザーとデータベースを作成しておきます。


$ sudo mysql -uroot
mysql> CREATE USER 'admin'@'%' IDENTIFIED BY 'P@ssw0rd';
mysql> GRANT ALL ON *.* TO 'admin'@'%';
mysql> quit



作成したユーザーで接続できるかテストし、データベースを作成します。


$ mysql -uadmin -p
Enter password:

mysql> CREATE DATABASE snipeit CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;





nginxの設定



nginxの設定を変更します。


$ sudo vi /etc/nginx/sites-enabled/default



変更箇所の抜粋です。


server {

        listen 80 default_server;
        listen [::]:80 default_server;

        root /var/www/snipe-it/public;

        # Add index.php to the list if you are using PHP
        index index.php index.html index.htm index.nginx-debian.html;

        server_name 192.168.1.102;

        location / {
                try_files $uri $uri/ /index.php;

                location = /index.php {
                        fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
                        fastcgi_param SCRIPT_FILENAME /var/www/snipe-it/public$fastcgi_script_name;
                        include fastcgi_params;
                }
        }
        location ~ \.php$ {
                return 444;
        }

}



nginxを再起動。


$ sudo service nginx restart



これで設置作業は完了です。




Pre-Flight



ブラウザで表示するとセットアップ画面が表示されます。

917_01.png

「Next: Create Database Tables」をクリックするとテーブルの作成が行われます。
結構時間がかかるようで通信がタイムアウトしました。

作成は途中まで進むようで、何回かこの画面でデータベース作成をクリックすると次に進めます。

917_02.png

初期ユーザーを作成。

917_03.png

これで画面が表示されました。

917_04.png


【参考URL】
https://snipe-it.readme.io/docs/installation
CentOS7 に Snipe-IT を導入
Snipe-IT を Ubuntu 16.04 LTS(AMI) に導入する
https://www.nginx.com/resources/wiki/start/topics/recipes/codeigniter/
Composer Security Conflict security-advisories with laravel 5.4.35

関連記事

テーマ:サーバ - ジャンル:コンピュータ

  1. 2018/08/25(土) 17:16:50|
  2. 備忘録
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集

Ubuntu Server 18.04.1 sources.listの変更点

nginx-extras
Ubuntu 18.04ではインストールできたのに、
Ubuntu 18.04.1ではインストールできなくて気が付きました。

sources.list



こちらが参考になりました。
Ubuntu 18.04.1を新規インストールするときはapt lineに注意しよう

/etc/apt/sources.listを比較してみます。

・Ubuntu Server 18.04


## Note, this file is written by cloud-init on first boot of an instance
## modifications made here will not survive a re-bundle.
## if you wish to make changes you can:
## a.) add 'apt_preserve_sources_list: true' to /etc/cloud/cloud.cfg
##     or do the same in user-data
## b.) add sources in /etc/apt/sources.list.d
## c.) make changes to template file /etc/cloud/templates/sources.list.tmpl

# See http://help.ubuntu.com/community/UpgradeNotes for how to upgrade to
# newer versions of the distribution.
deb http://archive.ubuntu.com/ubuntu bionic main restricted
deb-src http://archive.ubuntu.com/ubuntu bionic main restricted

## Major bug fix updates produced after the final release of the
## distribution.
deb http://archive.ubuntu.com/ubuntu bionic-updates main restricted
deb-src http://archive.ubuntu.com/ubuntu bionic-updates main restricted

## N.B. software from this repository is ENTIRELY UNSUPPORTED by the Ubuntu
## team. Also, please note that software in universe WILL NOT receive any
## review or updates from the Ubuntu security team.
deb http://archive.ubuntu.com/ubuntu bionic universe
deb-src http://archive.ubuntu.com/ubuntu bionic universe
deb http://archive.ubuntu.com/ubuntu bionic-updates universe
deb-src http://archive.ubuntu.com/ubuntu bionic-updates universe

## N.B. software from this repository is ENTIRELY UNSUPPORTED by the Ubuntu
## team, and may not be under a free licence. Please satisfy yourself as to
## your rights to use the software. Also, please note that software in
## multiverse WILL NOT receive any review or updates from the Ubuntu
## security team.
deb http://archive.ubuntu.com/ubuntu bionic multiverse
deb-src http://archive.ubuntu.com/ubuntu bionic multiverse
deb http://archive.ubuntu.com/ubuntu bionic-updates multiverse
deb-src http://archive.ubuntu.com/ubuntu bionic-updates multiverse

## N.B. software from this repository may not have been tested as
## extensively as that contained in the main release, although it includes
## newer versions of some applications which may provide useful features.
## Also, please note that software in backports WILL NOT receive any review
## or updates from the Ubuntu security team.
deb http://archive.ubuntu.com/ubuntu bionic-backports main restricted universe multiverse
deb-src http://archive.ubuntu.com/ubuntu bionic-backports main restricted universe multiverse

deb http://security.ubuntu.com/ubuntu bionic-security main restricted
deb-src http://security.ubuntu.com/ubuntu bionic-security main restricted
deb http://security.ubuntu.com/ubuntu bionic-security universe
deb-src http://security.ubuntu.com/ubuntu bionic-security universe
deb http://security.ubuntu.com/ubuntu bionic-security multiverse
deb-src http://security.ubuntu.com/ubuntu bionic-security multiverse

## Uncomment the following two lines to add software from Canonical's
## 'partner' repository.
## This software is not part of Ubuntu, but is offered by Canonical and the
## respective vendors as a service to Ubuntu users.
# deb http://archive.canonical.com/ubuntu bionic partner
# deb-src http://archive.canonical.com/ubuntu bionic partner




・Ubuntu Server 18.04.1


deb http://archive.ubuntu.com/ubuntu bionic main
deb http://archive.ubuntu.com/ubuntu bionic-security main
deb http://archive.ubuntu.com/ubuntu bionic-updates main



めちゃくちゃあっさりになっていますね。


不足分



今回、nginx-extrasをインストールしたかったので、
以下の3行を/etc/apt/sources.listに追記しました。


deb http://archive.ubuntu.com/ubuntu bionic restricted universe multiverse
deb http://archive.ubuntu.com/ubuntu bionic-security restricted universe multiverse
deb http://archive.ubuntu.com/ubuntu bionic-updates restricted universe multiverse



これでapt searchで発見できるようになりました。


$ sudo apt update
$ apt search nginx-extras
ソート中... 完了
全文検索... 完了
lua-nginx-memcached/bionic 0.10-1 all
Pure Lua memcached client driver for the nginx embedded Lua language

lua-nginx-redis/bionic 0.26-1 all
Pure Lua redis client driver for the nginx embedded Lua language

lua-nginx-websocket/bionic 0.06-1 all
Lua websocket client driver for the nginx embedded Lua language

nginx/bionic 1.14.0-0ubuntu1 all
small, powerful, scalable web/proxy server

nginx-extras/bionic 1.14.0-0ubuntu1 amd64
nginx web/proxy server (extended version)



関連記事

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2018/08/25(土) 15:41:50|
  2. 備忘録
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集
次のページ