bashスクリプトを使用して、次の有効で単純なIDを生成しようとしています。
{"name": "John", "surname": "Gates", "country": "Germany", "age": "20", "height": "180"}
{"name": "John1", "surname": "Gates", "country": "Germany", "age": "20", "height": "180"}
{"name": "John2", "surname": "Gates", "country": "Germany", "age": "20", "height": "180"}
{"name": "John3", "surname": "Gates", "country": "Germany", "age": "20", "height": "180"}
{"id": "XXX", "name": "John", "surname": "Gates", "country": "Germany", "age": "20", "height": "180"}
{"id": "XXX", "name": "John1", "surname": "Gates", "country": "Germany", "age": "20", "height": "180"}
{"id": "XXX", "name": "John2", "surname": "Gates", "country": "Germany", "age": "20", "height": "180"}
{"id": "XXX", "name": "John3", "surname": "Gates", "country": "Germany", "age": "20", "height": "180"}
約5,000,000件の類似レコードがあり、繰り返し可能で予測可能なIDを生成したいと思います。次のファイルの処理には時間が限られているため、Linuxシステムのsql liteデータベースから20分以内にこれを完了する必要があります。
MD5、SHA1は、AMD Ryzen 1900X CPUの16スレッドでGNU Parallelなどの操作を実行でき、数分で実行できない場合は使用するには高すぎます。
MD5を試してみましたが、1分45秒で28,000個のIDの計算が完了しました。 SHA1を使用すると2分3秒かかりました。
私は非常に簡単にIDを作成しようとしています。
JohnGatesGermany20180
John1GatesGermany20180
John2GatesGermany20180
John3GatesGermany20180
次の要件を満たす必要がある場合は、どの提案をしますか?
- 強く打つ
- Linux
- 5,000,000件のレコードを処理する必要があります。
- 20分以内
- 同じjson行の場合、IDは同じでなければなりません。
実行されたテスト:
#!/usr/local/bin/bash
while IFS= read -r line
do
uuid=$(uuidgen -s --namespace @dns --name "www.example.com" )
done < testfile1.txt
1,000,000行のmd5ハッシュ:
$time bash script.sh
real 13m6.914s
user 10m24.523s
sys 2m56.095s
cksum は 1,000,000 に対して crc チェックを実行します。
#!/usr/local/bin/bash
while IFS= read -r line
do
# uuid=$(uuidgen -s --namespace @dns --name "www.example.com" )
echo "$line $uuid"|cksum >> test3.txt
done < testfile1.txt
$time bash script.sh
real 12m49.396s
user 12m23.219s
sys 4m1.417s
ベストアンサー1
スクリプトが長すぎるのは、uuidgen
各行で実行しているからです。cksum
各プロセスを開始するだけで多くの時間が無駄になります。
5Mライン形式を{"name": "John%d", "surname": "Gates", "country": "Germany", "age": "20", "height": "180"}
tmpfsファイルシステム上のファイルに配置するには、次のPythonスクリプトが数秒で完了します。
#! /usr/bin/env python3
import hashlib
import sys
for line in sys.stdin:
print(hashlib.md5(line.rstrip('\n').encode('utf-8')).hexdigest())
実装する:
$ time ./foo.py < input > output
./foo.py < input > output 6.00s user 0.13s system 99% cpu 6.135 total
% wc -l input output
5000000 input
5000000 output
10000000 total
Pythonなので、行をJSONにデコードして各行にIDを挿入することもできます。次のような非効率的なコードもあります。
#! /usr/bin/env python3
import hashlib
import json
import sys
for line in sys.stdin:
l = line.rstrip('\n').encode('utf-8')
o = json.loads(line)
o["id"] = hashlib.md5(l).hexdigest()
print(json.dumps(o))
1分で完了:
% time ./foo.py < input > output
./foo.py < input > output 42.11s user 0.42s system 99% cpu 42.600 total
% head output
{"name": "John1", "surname": "Gates", "country": "Germany", "age": "20", "height": "180", "id": "2dc573ccb15679f58abfc44ec8169e52"}
{"name": "John2", "surname": "Gates", "country": "Germany", "age": "20", "height": "180", "id": "ee0583acaf8ad0e502bf5abd29f37edb"}
{"name": "John3", "surname": "Gates", "country": "Germany", "age": "20", "height": "180", "id": "a7352ebb79db8c8fc2cc8758eadd9ea3"}
{"name": "John4", "surname": "Gates", "country": "Germany", "age": "20", "height": "180", "id": "2062ad1b67ccdce55663bfd523ce1dfb"}
{"name": "John5", "surname": "Gates", "country": "Germany", "age": "20", "height": "180", "id": "5f81325c104c01c3e82abd2190f14bcf"}
{"name": "John6", "surname": "Gates", "country": "Germany", "age": "20", "height": "180", "id": "493e0c9656f74ec3616e60886ee38e6a"}
{"name": "John7", "surname": "Gates", "country": "Germany", "age": "20", "height": "180", "id": "19af9ef2e20466d0fb0efcf03f56d3f6"}
{"name": "John8", "surname": "Gates", "country": "Germany", "age": "20", "height": "180", "id": "2348bd47b20ac6445213254c6a8aa80b"}
{"name": "John9", "surname": "Gates", "country": "Germany", "age": "20", "height": "180", "id": "090a521b4a858705dc69bf9c8dca6c19"}
{"name": "John10", "surname": "Gates", "country": "Germany", "age": "20", "height": "180", "id": "fc3c699323cbe399e210e4a191f04003"}
私の仕様:
- インテル®Core™i7-8700 CPU @ 3.20GHz×12
- 2666MHz DDR4メモリ
uuidgen
私はあなたのスクリプトに基づいて4分で500,000行をかろうじて管理しました。出力を保存するように変更します。
#!/usr/bin/bash
while IFS= read -r line
do
uuidgen -s --namespace @dns --name "$line"
done < input > uuid
実装する:
% timeout 240 ./foo.sh
% wc -l uuid
522160 uuid