Оптимизация кода моего сценария для параллелей GNU - PullRequest
0 голосов
/ 29 мая 2018

У меня есть скрипт, который успешно запрашивает API, но очень медленно.Это займет около 16 часов, чтобы получить все ресурсы.Я посмотрел на то, как можно оптимизировать его, и подумал, что с помощью GNU-параллелей (установленных на macos через Brew, версия 20180522) все получится.Но даже при использовании 90 заданий (конечные точки API разрешают максимум 100 соединений) мой сценарий не работает быстрее.Я не уверен, почему.

Я называю свой сценарий так:

bash script.sh | parallel -j90

Сценарий следующий:

#!bin/bash 

# This script downloads the list of French MPs who contributed to a specific amendment.
# The script is initialised with a file containing a list of API URLs, each pointing to a resource describing an amendment


# The main function loops over 3 actions:
# 1. assign to $sign the API url that points to the list of amendment authors
# 2. run the functions auteur and cosignataires and save them in their respective variables
# 3. merge the variable contents and append them as a new line into a csv file 
main(){
local file="${1}"
local line
local sign
local auteur_clean
local cosign_clean

while read line
    do
        sign="${line}/signataires"
        auteur_clean=$(auteur $sign)
        cosign_clean=$(cosignataires $sign)
        echo "${auteur_clean}","${cosign_clean}" >> signataires_15.csv
done < "${file}"
}

# The auteur function takes the $sign variable as an input and 
# 1. filters the json returned by the API to get only the author's ID
# 2.use the ID stored in $auteur to query the full author resource and capture the key info, which is then assigned to $auteur_nom
#  3. echo a cleaned version of the info stored in $auteur_nom
auteur(){
local url="${1}"
local auteur
local auteur_nom

auteur=$(curl -s "${url}" | jq '.signataires[] | select(.relation=="auteur") | .id') \
&& auteur_nom=$(curl -s "https://www.parlapi.fr/rest/an/acteurs_amendements/${auteur}" \
| jq -r --arg url "https://www.parlapi.fr/rest/an/acteurs_amendements/${auteur}" '$url, .amendement.id, .acteur.id, (.acteur.prenom + " " + .acteur.nom)') \
&& echo "${auteur_nom}" | tr '\n' ',' | sed 's/,$//'
}

# The cosignataires function takes the $sign variable as an input and 
# 1. filter the json returned by the API to produce a space separated list of co-authors
# 2. iterates over list of coauthors to get their name and surname, and assign the resulting list to $cosign_nom
# 3. echo a semi-colon separated list of the co-author names
cosignataires(){
local url="${1}"
local cosign
local cosign_nom
local i

cosign=$(curl -s "${url}" | jq '.signataires[] | select(.relation=="cosignataire") | .id' | tr '\n' ' ') \
&& cosign_nom=$(for i in ${cosign}; do curl -s "https://www.parlapi.fr/rest/an/acteurs_amendements/${i}" | jq -r '(.acteur.prenom + " " + .acteur.nom)'; done) \
&& echo "${cosign_nom}" | tr '\n' ';' | sed 's/,$//'
}

main "url_amendements_15.txt"

и содержание url_amendements_15.txt выглядит так:

https://www.parlapi.fr/rest/an/amendements/AMANR5L15SEA717460BTC0174P0D1N7
https://www.parlapi.fr/rest/an/amendements/AMANR5L15PO59051B0490P0D1N90
https://www.parlapi.fr/rest/an/amendements/AMANR5L15PO59051B0490P0D1N134
https://www.parlapi.fr/rest/an/amendements/AMANR5L15PO59051B0490P0D1N187
https://www.parlapi.fr/rest/an/amendements/AMANR5L15PO59051B0490P0D1N161

1 Ответ

0 голосов
/ 29 мая 2018

Ваш скрипт перебирает список URL-адресов и последовательно запрашивает их.Вам нужно разбить его так, чтобы каждый запрос API выполнялся отдельно, поэтому parallel будет иметь команды, которые он может выполнять параллельно.

Измените сценарий, чтобы он занимал один URL.Избавьтесь от основной петли while.

main() {
    local url=$1
    local sign
    local auteur_clean
    local cosign_clean

    sign=$url/signataires
    auteur_clean=$(auteur "$sign")
    cosign_clean=$(cosignataires "$sign")
    echo "$auteur_clean,$cosign_clean" >> signataires_15.csv
}

Затем передайте url_amendements_15.txt на parallel.Дайте it список URL-адресов, которые могут обрабатываться параллельно.

parallel -j90 script.sh < url_amendements_15.txt
...