Odin Langの紹介

- 公式サイト : https://odin-lang.org/

## Odinとは？
OdinはCを代替する言語として開発されています。
本家サイトでは
"The Odin programming language is fast, concise, readable, pragmatic and open sourced."
と紹介されており、安全性よりは高速性や可読性を重視しています。
文法はGolangに似ています。

## インストール
https://odin-lang.org/docs/install/
筆者の環境がWindowsな為、Windowsのみ紹介します。

0. Visual Studioのインストール
https://visualstudio.microsoft.com/ja/downloads/
OdinではVSに同梱されているlink.exeを使用するため、インストールします。
Community EditionでOKです。

1. Odinのダウンロード
https://github.com/odin-lang/Odin/releases
2019/9/26 時点の最新版であるv0.10.0を使用していきます。
windows-amd64.zipをダウンロードします。
このバージョンではLLVMのバイナリが同梱されているので、LLVMの手順はスキップします。  
ダウンロードが完了したら、解凍しましょう。odinフォルダの中にodin.exeが入っています。

## 実行
Odinを実行するには"x64 Native Tools Command Prompt"で実行する必要があります。
スタートメニューで検索し、起動します。
![コメント 2019-09-28 114337.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182505/ef1824c7-4089-cfc9-dd06-ca20bafc82d6.png)

![コメント 2019-09-28 115253.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182505/3bf45d22-1f92-c20a-321b-5b46050061f2.png)
スタートメニューにあるプロンプトの実体は"vcvarsall.bat"を叩いているだけなので、このbatをVSCodeでタスク実行することも可能です。(後述します。)

プロンプト起動に成功したらHelloWorldを試します。

```go:hw.odin
package main

import "core:fmt"

main :: proc() {
    fmt.println("Hellope!");
}
```

hw.odinをプロンプトで実行します。

```bash
$ "Odin.exeのパス" run "hw.odinのパス"
$ Hellope!
```

## VSCodeとの連携
※興味がない場合は飛ばして頂いて構いません。
コンパイル言語はコーディング >> コンパイル >> 実行のワンステップを挟むので、
ショートカットキー押すだけで実行できればモチベも上がるってもんです。
ここでは成功した、VSCodeからバッチファイルを起動する方法を紹介します。
※これよりシンプルな方法を御存知であればご教授願います。

### バッチファイルの作成
```bash:build.bat
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat"
call """odin.exeのフルパス""" run "%1"
exit
```

### タスクの作成
```json:tasks.json
{
    "version": "2.0.0",
    "tasks": [
        {
            "label":"build Odin",
            "type":"shell",
            "command":"""build.batのフルパス""",
            "args":[
                "${file}"
            ],
            "presentation": {
                "echo": true,
                "reveal": "always",
                "focus": false,
                "panel": "shared",
                "showReuseMessage": false,
                "clear": false
            },
            "group": {
                "kind": "build",
                "isDefault": true
            }
        }
    ]
}
```

### 動作確認
先程のhw.odinを開いて動作確認します。
"Ctrl + Shift + B"で実行してみましょう。

```powershell:VSCode_console
> Executing task in folder Odin: ...
D:\Repos\Odin>call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat"
**********************************************************************
** Visual Studio 2019 Developer Command Prompt v16.1.1
** Copyright (c) 2019 Microsoft Corporation
**********************************************************************
[vcvarsall.bat] Environment initialized for: 'x64'
Hellope!
```

これにて無事VSCodeから直接実行する環境が整いました。
手軽に実行できるのがいいですね。

## パフォーマンス比較

### 計測方法
Powershellにて確認しています。

```powershell:console
Measure-Command {"実行するexe"}
```

### 結果
早速ですが、パフォーマンス比較を実施します。C言語と比較した結果が以下です。

| 使用関数    |フィボナッチ | ライプニッツ級数 |
|:-----------|-----------:|----------------:|
|C           |647.4248 ms |4807.0341 ms|
|C (-OFast)  |469.6748 ms |195.2315 ms|
|Odin        |40.8608 ms  |729.5093 ms|
|Odin(-opt=3)|24.3634 ms  |26.2991 ms|
|rust        |44.0257 ms  |19548.6786 ms|
|rust(opt=3) |17.2909 ms  |14.2931 ms|

Odin速っ！で終わらせたかったのですが、Rustめちゃ速いですね...。
ただ、Odinも引けを取らない速さです。
どちらもCより速いのが驚きですね。

※Rustがライプニッツ級数で遅いのは計算の度に値チェック等しているのでしょうか？


### 使用関数
※他にパフォーマンス図るのにいい例がありましたらご教授ください。

#### フィボナッチ

```c:Fibonacci.c
int fib(int n){
    if (n <= 1){
        return 1;
    }
    else{
        return fib(n-1) + fib(n-2);
    }
}
int main(){
    int r = fib(32);
    return 0;
}
```

```go:Fibonacci.odin
package main

main :: proc() {
    fib(32);
}
fib::proc(n:i64) -> i64{
    if n <= 1{
        return 1;
    }
    else{
        return fib(n-1) + fib(n-2);
    }
}
```

```rust:Fibonacci.rs
fn fib(n:i64) -> i64{
    if n <= 1{
        return 1;
    }
    else{
        return fib(n-1) + fib(n-2);
    }
}

fn main() {
    let _r = fib(32);
}
```

#### ライプニッツ級数

```c:LeibnizFormula.c
# include <stdio.h>
# include <math.h>
void main(void){
  double i;
  double s = 0.0;
  for(i = 0; i<=1e8; i++){
    s += pow(-1.0, i) / (2.0 * i + 1.0);
  };
}
```

```go:LeibnizFormula.odin
package main
import "core:math"

main :: proc() {
    i : f64;
    s : f64 = 0.0;
    for i = 0; i<=1e8; i+=1 {
        s += math.pow(-1.0, i) / (2.0 * i + 1.0);
    }
}
```

```rust:LeibnizFormula.rs
fn main(){
    let _i : i64;
    let mut _s : f64 = 0.0;
    for _i in 0..=1e8 as u32{
        _s += (-1_i32.pow(_i) / (2 * _i + 1)as i32) as f64;
    }
}
```

## 後日加筆予定