同期処理と非同期処理（async/await）



## はじめに
同期処理と非同期処理（async/await）に関しての備忘録。

## 🦁<INS>**結論**</INS>🦁
処理時間を向上させる上で
「非同期処理」と「並列処理」は必須。
まずは処理自体に
「同期処理」と「非同期処理」があることを理解して、「非同期処理に分類されるもの」or「非同期処理として明示するもの」とがあることを理解することが大事。

選定して組立してコードを加える必要がある。

並列処理は別のもので別の記事でアップ予定。
（私は並列処理を混同させてしまって混乱してしまった。）

:::note info
同期処理のポイント
* 上から順番に一つずつ完了させる処理（逐次処理）
* 前の処理が完了しないと次の処理が始まらない。
* 可読性は高く、理解しやすい。
* 処理時間に時間がかかる。
:::  

## <INS>**同期処理の例（非同期処理をできないもの）**</INS>
## <INS>**forでのループ処理**</INS>
コレクション内のアイテムを順に処理する。
```py
for item in collection:
    process(item)
```


## <INS>**pandasなどを使っての表計算**</INS>
pandasを使ったdfなど表計算処理。

```py
import pandas as pd

# CSVファイルを読み込む（同期処理）
df = pd.read_csv('data.csv')

# データに何らかの変換を適用（同期処理）
df['new_column'] = df['existing_column'].apply(some_transformation)

# 結果を新しいCSVファイルに書き出す（同期処理）
df.to_csv('transformed_data.csv')
```


## <INS>**文字列の操作**</INS>
文字列の結合や置換を行うなどの処理。

```py
greeting = "Hello, " + name
```

## <INS>**ファイルの拡張子の変更**</INS>
ファイルの拡張子の変更などを行う。
```py
import os

original_filename = 'example.txt'
new_filename = 'example.csv'

# ファイルの拡張子を変更（同期処理）
os.rename(original_filename, new_filename)
```


## <INS>**データの解析**</INS>
ローカルに保存されてるデータの解析を行う。

```py
# ファイルを開いてデータを読み込む
with open('data.txt', 'r') as file:
    # ファイルから各行を読み込む
    for line in file:
        # 改行文字を取り除き、カンマで各値を分割する
        values = line.strip().split(',')
        # 分割した値を処理する（例：型変換や計算など）
        processed_values = [float(value) for value in values]
        # 処理した値のリストを出力
        print(processed_values)

# この例では、各行に含まれる値を浮動小数点数に変換し、それをリストとして出力しています。
```
***  



:::note warn
非同期処理のポイント
*  ローカル以外の部分とのやりとり（I/Oなど）を行われた時にいつ完結するのかが自身の環境外の部分で行われるもの
* 非同期処理をするためには関数や処理部分などにコードを書き加える必要がある <INS>**（asyncをつけないと、非同期処理が完了するのを待った後に、後続処理が入る）**</INS>
* 関数にはasync、処理部分にawaitを頭に付け加える。
* 
:::  

## <INS>**非同期処理するべきもの一覧**</INS>

## <INS>**外部APIでのデータ読み込み**</INS>
Web APIから非同期にデータを取得する。

```py
import aiohttp
import asyncio

async def fetch_data(url):
    async with aiohttp.ClientSession() as session:
        async with session.get(url) as response:
            return await response.text()

asyncio.run(fetch_data('https://example.com/api/data'))
```


## <INS>**非同期ファイルI/O操作**</INS>
ディスクからのデータ読み込みや書き込みを非同期で行う。
```py
import asyncio
import aiofiles

async def read_file_async(filename):
    async with aiofiles.open(filename, mode='r') as f:
        return await f.read()

asyncio.run(read_file_async('async_file.txt'))
```


## <INS>**Webスクレイピング**</INS>
ウェブページから非同期にデータを取得し解析を非同期で行う。

```py
import aiohttp
import asyncio

async def fetch_page(url):
    async with aiohttp.ClientSession() as session:
        async with session.get(url) as response:
            return await response.text()

asyncio.run(fetch_page('https://example.com'))
```


## <INS>**画像や動画の非同期ダウンロード**</INS>
大きなファイルを非同期にダウンロードする。

```py
import asyncio
import aiohttp

async def download_file(url):
    async with aiohttp.ClientSession() as session:
        async with session.get(url) as resp:
            if resp.status == 200:
                with open("output_file", 'wb') as f:
                    f.write(await resp.read())

asyncio.run(download_file('http://example.com/image.png'))
```

## まとめ✍️
処理時間を向上させることで私が作成したものを扱ってくれる方が喜ばれるはずなので、今後どんどん使っていく。

非同期処理を理解するのはだいぶ混乱した。（まだ一部しか理解してないけど💦）
非同期処理と並列処理を一緒に使うことが多いから混同させてしまってだいぶおかしな理解になったが、メンターに正してもらいしっかり教えてもらって理解が深まりました。
誰かにチェックしてもらう大事さも深まりました。
  
## 参考にした記事📕
[並列処理と非同期処理の徹底マニュアル](https://mama-lifestyle.jp/swift-dev-jp/async/)
[Python multiprocessing vs threading vs asyncio](https://tech.jxpress.net/entry/2021/07/29/101150#マルチプロセスmultiprocessingライブラリを利用したほうが良い場合)