🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

並列処理

複数の計算が同時に実行される手法

マルチスレッド

マルチスレッドは、どのように機能がコンピュータによって実行したのかを、(一般的にはスレッドとして参照される)実行の複合的な共同作用するストリームへ区分することが出来ます。

非同期処理

非同期処理とは一部のコードを別々のスレッドで実行させる手法です。アプリケーションのパフォーマンスを向上させる目的でこの手法を用います。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

1419閲覧

[python]マルチスレッドでjsonを返却する方法

pokemonta

総合スコア170

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

並列処理

複数の計算が同時に実行される手法

マルチスレッド

マルチスレッドは、どのように機能がコンピュータによって実行したのかを、(一般的にはスレッドとして参照される)実行の複合的な共同作用するストリームへ区分することが出来ます。

非同期処理

非同期処理とは一部のコードを別々のスレッドで実行させる手法です。アプリケーションのパフォーマンスを向上させる目的でこの手法を用います。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/03/08 05:17

編集2021/03/08 09:07

やりたいこと
部署IDをマルチスレッドで渡しそれぞれ部署に所属する人の
属性情報を抽出して、最終的にはクライアントにjsonを1つ返却したいです。

json

1{ 2 "devId" : 111 3 personList :[ 4 {'personId' : a1, 5 'attr' : "販売員"}, 6 {'personId' : a2, 7 'attr' : "会計員"}, 8 ] 9}, 10{ 11 "devId" : 222 12 personList :[ 13 {'personId' : c1, 14 'attr' : "エンジニア"} 15 ] 16}

python

1 2dest = dict() 3dest.setdefault("items",[]) 4 5 6def lambda_handler(devIdList): 7 8 tpe = ThreadPoolExecutor(max_workers=len(devIdList), thread_name_prefix="thread") 9 result = list(); 10 11 for devId in devIdList: 12 future = tpe.submit(main,devId) 13 result.append(future); 14 tpe.shutdown() 15 16 for future in result: 17 List.append(future.result()) 18 19 return { 20 'headers': { 21 'Content-Type': 'application/json', 22 'Access-Control-Allow-Origin': '*' 23 }, 24 "body": json.dumps([i for i in List]) 25 } 26 27 28 29def main(devId): 30 #部署idを渡すと所属員を抽出 31 result = GETDevPerson(devId) 32 33 if result is not None: 34 if len(result['devIdList']) != 0: 35 dest11 = dict() 36 dest11.setdefault("devId",devId) 37 38 #所属員の詳細情報を抽出 39 for personId in result['devIdList']: 40 41 result = GETPersonattribute(personId) 42 43 if result is not None: 44 dict1 = { 45 'personId' : personId, 46 'attr' : result['attr'] 47 } 48 49 50 dest11["personList"].append(dict1) 51 dest["items"].append(dest11) 52 return dest 53 54

マルチプロセスを実装しても性能が全然向上しません。
どんなデータが取得できるのか細かく記載していないため
回答が難しいとは思いますが
実装方法に問題があるのでしょうか

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

極力元のコードから変えないようにするなら、下記のような感じになるでしょうか。
(※18:07に質問が修正される前の質問文に対して作った回答のため、現時点の質問内容に対しては参考にならないかもしれません)

python

1from concurrent.futures import ThreadPoolExecutor, wait 2import json 3 4# dest = dict() 削除 5# dest.setdefault("items",[]) 削除 6 7def lambda_handler(devIdList): 8 9 tpe = ThreadPoolExecutor(max_workers=len(devIdList), thread_name_prefix="thread") 10 List = list() 11 12 for devId in devIdList: 13 future = tpe.submit(main, devId) 14 List.append(future) 15 wait(List) 16 tpe.shutdown() 17 18 return { 19 'headers': { 20 'Content-Type': 'application/json', 21 'Access-Control-Allow-Origin': '*' 22 }, 23 "body": json.dumps([i.result() for i in List]) 24 } 25 26 27def main(devId): 28 #部署idを渡すと所属員を抽出 29 result = GETDevPerson(devId) 30 if result is not None: 31 if len(result['devIdList']) != 0: 32 dest11 = dict() 33 dest11.setdefault("devId", devId) 34 dest11.setdefault("personList", []) 35 36 #所属員の詳細情報を抽出 37 for personId in result['devIdList']: 38 39 result = GETPersonattribute(personId) 40 41 if result is not None: 42 dict1 = { 43 'personId' : personId, 44 'attr' : result['attr'] 45 } 46 dest11["personList"].append(dict1) 47 return dest11

並行処理にならない例

from concurrent.futures import ThreadPoolExecutor import time def lambda_handler(devIdList): tpe = ThreadPoolExecutor(max_workers=len(devIdList)) List = list() for devId in devIdList: future = tpe.submit(main, devId) # submit直後にfuture.result()を呼び出しているため、futureが完了するまでループはブロックされる(このfutureが完了するまで次のsubmitがなされない)。 List.append(future.result()) tpe.shutdown() return [i for i in List] def main(devId): print(f"main()が呼ばれました. 引数devIDは[{devId}]です。5秒間停止します。") time.sleep(5) print(f"main()から戻ります。 引数devID:[{devId}]") return str(devId)+"_finished." idlist = [10, 20, 30] print(lambda_handler(idlist))

 

並行処理になる例

from concurrent.futures import ThreadPoolExecutor, wait import time def lambda_handler(devIdList): tpe = ThreadPoolExecutor(max_workers=len(devIdList)) List = list() for devId in devIdList: future = tpe.submit(main, devId) # futureだけをリストに格納する。result()としていないので、すぐループして次のsubmitが起こる。 List.append(future) wait(List) # List内のfutureが全部完了するまで待つ(実際はこのwaitの行がなくても、結果自体は変わらない) tpe.shutdown() # futureの結果をリストにして返す。 return [i.result() for i in List] import random def main(devId): print(f"main()が呼ばれました. 引数devIDは[{devId}]です。5秒間停止します。") time.sleep(5) print(f"main()から戻ります。 引数devID:[{devId}]") return str(devId)+"_finished." idlist = [10,20,30] print(lambda_handler(idlist))

投稿2021/03/08 10:00

編集2021/03/08 14:05
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

pokemonta

2021/03/08 12:19 編集

ありがとうございます すみません。ソースコードが以前と変わっているのはわかったんですがどのような観点で 変更されているのでしょうか? 私のコードは何がまずいのでしょうか? マルチスレッドになっていませんでしたか? (性能が出ないので並列で処理されていないのではと懸念してます)
pokemonta

2021/03/08 12:23

max_workers=の値を2とか10に変えても早くなりません
退会済みユーザー

退会済みユーザー

2021/03/09 02:45 編集

polemontaさんが18:07に質問内容を修正する「前」のコードを見て回答を作ったので、私の回答内容は今となってはあまり参考にならないかもしれません。 修正後のコードは、Listの定義がどこにもなくそのままではエラーになってしまう部分を修正すれば、並行処理はできているようには見えます。 なお、こちらの実行環境としてはローカルでしか試しておりません。 仮にローカルではなくamazon lambdaで実行されている場合は、amazon lambda固有の要因で結果が異なる(性能が出ていない)可能性はあります。(その固有の原因というのはわかりません) また、明らかにされていないGETDevPersonやGETPersonattributeの処理内容が原因で性能が出ていない可能性もあります。こちらも明らかにされていない以上、原因はわかりません。
pokemonta

2021/03/08 23:40 編集

GETDevPersonやGETPersonattributeでも 並列処理しないと行けないかもしれません  (打つ手がなくて困ってます。あとは、上記を並列化するぐらいしか)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問