只有累積,沒有奇蹟

2022年11月7日 星期一

[NETCore] String 字串相加效能比較

前言
在 .NET 應用程式中很常使用到 string 型別,string 是不可變 ( Immutable ) 的,當每次建立完就會固定其長度,如果要做相加就必須捨棄原有使用的記憶體,在重新配置一塊新的記憶體給它使用,如果在需要大量得字串動態相加時就會影響到其效能,因此在動態文字相加情境就可以透過 stringBuilder 來改善此問題,詳細細節可以參考黑暗大的 StringBuilder串接字串的迷思,這篇重點是在 C# 有提供多種語法來做 string 相加語法,像是 string.Format、stringBuilder、Concat、Join 以及 Interpolation 多種方法,今天就要針對 C# 中提供的字串相加效能進行比較,以及測試的結果數據,若有問題或是錯誤的地方歡迎各位給予指導及討論

測試代碼 
測試方式以  BenchmarkDotNet  套件協助進行測試,BenchmarkDotNet 可以針對要測試的方法紀錄執行時間,並會將測試結果輸出報告,如果對此套件有興趣可以參考介紹的文章 [.NETCore] 使用 BenchmarkDotNet 測試程式碼效能首先先針對固定字串相加做測試,定義區域變數 firstWord 與 secondWord 希望輸出 This is a book 字眼,另外在 stringBenchmark 類別加上  ClrJob,CoreJob  希望分別在 .NET Framework 與 .NET Core 測試效能差異,加上  MemoryDiagnoser  輸出測試時觀察 GC 的結果,代碼如下 
namespace benchmarkLab
{
    class Program
    {
        static void Main(string[] args)
        {
            var summary = BenchmarkRunner.Run<stringBenchmark>();
            Console.ReadKey();
        }
    }

    [MemoryDiagnoser]
    [ClrJob,CoreJob]
    public class stringBenchmark
    {
        private static string firstWord = "This is a";
        private static string secondWord = "book";
        StringBuilder _sb = new StringBuilder();

        // 測試代碼
    }
}
使用 Benchmark 測試數據,需要在方法上加上 Benchmark  attribute,使用 string 的相加測試的代碼如下
[Benchmark]
public void Normal()
{
    string s = string.Empty;
    s = firstWord;
    s += secondWord;
}
使用 stringBuilder 的相加測試的代碼如下
[Benchmark]
public void StringBuilder()
{
    StringBuilder sb = new StringBuilder();
    sb.Append(firstWord);
    sb.Append(secondWord);
    string s = sb.ToString();
}
另外一種使用 stringBuilder 的方式,將其宣告為區域變數使用前先 clear,測試的代碼如下
[Benchmark]
public void StringBuilderClear()
{
    _sb.Clear();
    _sb.Append(firstWord);
    _sb.Append(secondWord);
    string s = _sb.ToString();
}
使用 string.Format,測試的代碼如下
[Benchmark]
public void Format()
{
    string s = string.Empty;
    s = string.Format("{0} {1}", firstWord, secondWord);
}
使用 C# 6.0 提供的新語法 Interpolation,測試的代碼如下
[Benchmark]
public void Interpolation()
{
    string s = string.Empty;
    s = $"{firstWord}{secondWord}";
}
使用 string.Concat,測試的代碼如下
[Benchmark]
public void Concat()
{
    string s = string.Empty;
    s = string.Concat(firstWord, secondWord);
}
使用 string.Join,測試的代碼如下
[Benchmark]
public void Join()
{
    string s = firstWord;
    s += string.Join(s, secondWord);
}
接著調整到 Release mode,按下 F5 進行測試
測試完成後,會產生測試報各路徑在  release\BenchmarkDotNet.Artifacts\results  目錄底下,如下圖所示
根據測試結果


  • .NET Framework : 表現最差的為 string.Format,表現最好的是 string 相加
  • .NET Core : 表現最差的為 string.Format,表現最好的是 Interpolation

  • 感想
    透過結果得知,在 .NET Framework 與 .NET Core 環境中在 靜態字串 相加的情況下,string 相加效能會比使用 stringBuilder 來的好 (原因可以參考黑暗大文章 StringBuilder串接字串的迷思,這裡就不在細說),Interpolation 與 conact 落後一些也是表現不錯,唯有 string.Format 在兩個皆墊底,.NET Framework 最好與最差的差距近 6 倍 ( 31.9 v.s 238.0 ),在 .NET Core 更高達 9 倍 (38.2 v.s 312.2 ),如果有需要用到時需要特別留意,避免影響到網站執行效能,下次再來分享動態文字的測試數據 (拖稿),Happy Coding :)

    參考
    在 ASP.NET Core 中使用多個環境

    2022年10月28日 星期五

    [Linux] 跨平台 SSH Client 工具 - Termius

    前言
    身為一個 Windos 重度用戶來說,近期要切換到 Linux 環境開發無疑是個重大挑戰,建置 CentOS 環境的第一步必須先連到遠端的 Linux Server,同事大力推薦  Terminus ,此工具支援 mac 以及 windows 且適用於 desktop 以及 mobile 版本,重點還免費,對 Linux 新手當然是一大福音,這篇簡單紀錄 Terminus 工具的安裝與使用方式,分享給跟我對於 Linux 還在摸索的新手朋友們。

    安裝 Termius
    安裝傳送門 : 請點我 
    Step 1 : 公司筆電是 Windows 因此下載 Termius for Windows 版本
    另外也同時支援 Mobile、Mac、Linux,如果在 Windows 使用系統會同步至 mobile 版本
    Step 2 : 點選取得,會開始進行下載
    如果是第一次使用,會建議要求註冊帳號的動作
    Step 3 : 安裝完畢之後,第一次使用會跳出介紹說明

    使用 Termius
    主要視窗畫面如上,畫面我覺得是相當不賴
    如果不喜歡深色系的話,可以點選左上角 > Terminal,選擇自己喜歡的顏色或是字形大小

    新增連線
    在主視窗右下角,點選  +NEW HOST 
    輸入遠端資訊資訊,名稱、IP 相關設定,輸入完畢後按下右上角 Save
    新增完畢後,點擊後會跳出輸入帳號密碼
    即可順利進去 Linux server

    結語
    好的,以上是 Termius 最簡單的操作方式,使用上相當容易上手沒太多難度,已列入我個人私藏工具之一,工具有提供更多好用的功能與說明,如果想了解更多資訊可以了解 Termius 官網介紹


    2022年10月17日 星期一

    [conference] MOPCON 2022 - 無密碼時代來臨 ? 初探 FIDO 驗證標準

    分享心得
    這幾年無密碼議題越來越夯,去年在 Apple 開發者大會也有 Presskey 讓相關議題更火紅,在去年初就有聽主管聽到 FIDO 相關技術議題,一直希望有時間研究相關議題在公司產品整合既有服務,於是自己就花自己時間研究很多這好玩的議題,整理完後並在 Mobile Open Platform Conference 分享最近研究的驗證議題 《FIDO》,現場分享時隨著人數暴增緊張程度跟說話速度也加快,自己並未想到會有這麼多人會來聽,也因為緊急過頭原本提早結束,提早進入 QA 階段,希望有在場聽得受眾聽完有幫助,對於 QA 的回覆也有幫助到各位,如果對投影片內有任何 feedback 歡迎留言或私訊給我


    議程介紹
    主題 : 無密碼時代來臨 ? 初探 FIDO 驗證標準
    密碼一直是讓人又愛又恨的東西,隨著網路的世界越來越複雜,對於密碼複雜度與安全性的要求也越來越高,不時資安大廠都會發表關於密碼外洩的新聞,使用者為了方便使用相同帳密遭到破解造成的經濟損失不計其數,有沒有一個更好更安全的方式可以解決困擾已久問題呢 ?
    無密碼認證(Passwordless Authentication)技術在這幾年越來越多人開始討論,在今年全球密碼日當天,Google、微軟、蘋果共同發出聲明將支持 ( FIDO Fast Identity Online)身分認證方式,為何科技大廠會選擇 FIDO 網路身分驗證呢 ? 其背後的原理到底是如何做到無密碼登入的呢 ? 手機裝置要如何支援呢 ? 在這 Session 預計與大家分享
    1. 甚麼是 FIDO
    2. 原理與特性
    3. FIDO 的下一步
    

    主辦單位 : MOPCON
    議程表 : 連結
    投影片 : 連結



    2022年9月17日 星期六

    [conference] DevopsDays 2022 - 可觀測性(Observability)的實踐

    分享心得
    這兩年因緣際會接觸可觀測性(Observability)這議題,研究後覺得挺有趣於是不要臉的報名 DevopsDays Taipei 研討會分享,也很幸運地獲得評審青睞有機會在今年 DevopsDays 2022 分享,這次分享有兩個大的挑戰分別是議程內容與時間
    1. 議程內容 : 指的是在過去雖然有在 .NET Conf 2021 分享過一小段,但要在這麼大的場合要把 Observability 說明清楚是個不容易的事情,尤其是這議題在國內比較少看到有人提到,因此很多時間在看國外研討會影片或是文章來釐清自己的觀念與想法。
    2. 時間 : 由於議題只有 25 分鐘,可觀測性到底是甚麼 ? 想要解決甚麼問題 ? 它與監控差異到底在哪裡呢 ? 觀念說明完再提到實踐工具有哪些,要在短時間把資訊整理清楚並說讓第一次的會眾了解是個很大的挑戰,也有試著把整理的內容給幾位強者同事分享看是否哪裡不清楚的地方,強者同事也聽完給很多實用的建議,整個投影片內容修改不下 20 次才完成初版 (頭髮都白了 XDDD
    由於之前都太緊張所以都沒注意到場地,當天實際閒晃到場地才傻眼過去分享都是比較小場地這次被安排到 ABC 會議室,心裡只能默默祈禱今天準備內容不要太掉漆就好,幸好過程中還算順利準備的議題都有分享到,會後也有很多朋友詢問相關議題與實作細節,護國神山也有 HR 與主管來找我聊聊(但太緊張完全忘記說啥 XDD),結束緊張又刺激的一天。
    一個月後傍晚收到 DevOpsDays Taipei 活動的議程問卷調查,過去參加 DevOpsDays 都是站在台下當聽眾,沒想到會有一天站在 #DevOpsDays 台上分享感到很開心,感謝當天議程與會者的建議跟留言,也期許自己未來還有機會分享自己研究的心得 :)


    議程介紹
    主題 : 可觀測性(Observability)的實踐
    隨著科技不斷的進步與雲端的普及,企業軟體在架構的演進與應用程式開發的速度與越來越快,隨之而來的挑戰是開發人員如何針對這些服務進行更好的監控(Monitor),以提供高可用性的服務。
    可觀測性(Observability)在這幾年越來越多人在討論,甚至在 CNCF 還有專區介紹 Observability 相關的工具,可觀測性與監控到底有何不同?為何國外大型研討會與雲端廠商都開始提到可觀測性?
    這主題將會分享以下內容
    ➊ 什麼是 Observability ?
    ➋ 可觀測性 vs 監控 
    ➌ 實踐工具
    

    主辦單位 : DevOpsDays Taipei
    議程表 : 連結
    共筆 : https://hackmd.io/@DevOpsDay/2022/%2F%40DevOpsDay%2FBkLestagj
    投影片 : 連結



    2022年9月3日 星期六

    [Testing] Playwright : 現代化的跨瀏覽器自動化測試框架

    前言
    在前一篇 [Tool] END-TO-END Test 測試工具 - Playwright 介紹好用的 open source 工具 Playwright,過了一年 Playwright 功能越來越強大自己也花了點時間研究,這篇文章就來針對這套好用的開源工具繼續推坑,若有問題歡迎提出來一起討論。

    E2E Testing
    在提到 Playwright 之前,想要先提一下什麼是 end to end testing,查詢 wiki 可以得到下列解釋

    End-to-End Testing (E2E testing) refers to a software testing method that involves testing an application’s workflow from beginning to end. This method basically aims to replicate real user scenarios so that the system can be validated for integration and Data Integrity.
    它是軟體開發生命週期(SDLC)中使用的一種方法,目標是模擬真實用戶場景從頭到尾的樣子,目的是為了確保子系統案預期工具與行為。上述聽起來可能會覺得很抽象,或者是可能在過去工作上聽過很多不同的名詞,聽完上述描述可能更容易讓人混淆,像是單元測試、E2E 測試、整合測試與 UI 測試,那麼這幾個有什麼不同呢 ? 我們可以透過這張圖來讓大家更容易了解這之間的差異

    圖片來源 : Microservices Testing Strategies, Types & Tools: A Complete Guide

    這是一張經典的測試金三角圖,裡面說明了單元測試、整合測試、E2E 測試、與 UI 測試之間的差異
    • 單元測試 : 紅色框部分,開發人員在撰寫程式時針對模組進行驗證的測試
    • 整合測試 : 藍色框部分,不同模組之間呼叫行為是否符合預期,上圖例子是前端與後端開發完後進行測試動作
    • E2E 測試 : 橘色框部分,上圖例子是前端與後端開發完後,再與其他服務(Service) 及資料庫多個服務進行測試
    • UI 測試 : 灰色框部分,上圖例子是使用 Client App 來呼叫後面服務(Service),驗證功能是否如預期
    核心概念都是透過「預期結果(expect)」和「真實結果」去做比對,驗證兩者是否相同,不同測試就會驗證失敗再請工程師去察看哪邊出了問題要進行修正的動作。了解這些測試可能的差異之後,在實際執行上還要考慮的點是測試範圍、時間、成本等三個重要因素,因為各自所測試的守備範圍與顆粒度不同,勢必也會影響到測試人員或是開發人員所花費的時間,進而也會有執行成本的議題產生,因此在執行上也須要多考量這些因素。


    E2E Testing 挑戰
    在執行上可能會遇到很多大大小小的挑戰,我這裡列出我覺得在執行上可能比較重要的兩點 : 瀏覽器支援螢幕解析度

    瀏覽器支援
    由於使用者習慣的不同,所在國家政策與安全考量不同,因此在瀏覽器的分布上是相對沒那麼集中,如果要在測試時支援多個瀏覽器可能遇到的挑戰是在測試時就要在不同的瀏覽器上進行測試,來看其功能與 UI畫面是否與預期長的相同,功能不會有異常與意外,要花費的時間勢必要多少時間。

    螢幕解析度
    談完瀏覽器,下一個要關心的議題是螢幕解析度的部分。越來越多人使用手機與平板來瀏覽網頁,大家在使用的 Device 的螢幕尺寸與解析度都不相同,因此開發出來的網頁要如何在不同的螢幕正常呈現也是很重要的。
    圖片來源 : Infographic: Fragmentation in OS, browsers, and devices

    簡單總結一下 E2E 測試會遇到的挑戰
    • 瀏覽器 : 瀏覽器的種類型態不同,開如何支援與決定不支援那些 ?
    • 學習曲線 : 簡單來說就是 E2E 測試工具好不好學,是不是容易上手對團隊來說是個重要的議題
    • 穩定性 : E2E 測試可能是一直需要持續修改的,要在每次執行的過程可以重複執行不出錯,資料的準備也是重要的關鍵
    • 維護成本 : 隨著產品功能不斷的迭代,程式碼會一直不斷的修改,要如何確保測試案例可以一直正常執行,或是當心功能上線時可以快速進行相關調整也很重要


    Playwright
    Playwright 是一套現代化可靠的 e2e 測試工具,他是由微軟開源的,第一個版本是由微軟在 2019 年底 release,經過兩年的時間越來越火紅。根據熱門 Best of JS 網站的資料顯示,在 Testing tools 中 Playwright 佔據第一名,可以說是相當地受到開發者的歡迎與喜愛。

    Why Playwright ?
    Playwright 有很多強大的功能與特性,我這邊有整理自己覺得對開發者來說重要的六大特性,分別是
    • Cross Browser
    • Cross Language
    • Auto Retry/wait
    • Browser Contexts
    • Tracing
    • Powerful Tooling
    接下來依據這六個特性來做簡單的說明


    Cross Browser
    Playwright 支援了所有現代化的 render 引擎,包括 Chromium, WebKit 和 Firefox,因此幾個主流的瀏覽器像是 Chrome、Edge、Firefox、Opera 都支援。如果要對網頁做相容信測試 Playwright 是一个很好的選擇。也解決了前面提到 E2E 挑戰的第一點。

    Cross Language
    支援多程式語言,提供多種程式語言的 API,包括 TypeScript、JavaScript、Python、.NET 和 Java。跨程式語言帶來甚麼好處呢 ? 可以選擇自己熟悉的程式語言開發測試的腳本。這邊官方有更詳細的說明,詳細可以到 playwright.dev 看更詳細的資料。

    Auto Retry/wait
    舉個實際案例,假設我們有個登入頁面,登入 page 有帳號密碼欄位要輸入其中帳號欄位要輸入時會自動檢查格式內容是否正確,檢查邏輯是在檢查格式過程中登入按鈕是沒辦法輸入的。
    一般來說,我們所撰寫的測試腳本會按照你的程式碼逐行往下執行(肉眼跟不上的速度),因此在沒有 autowait 功能的情況底下,這種測試案例在執行上是很容易執行失敗的(因為無法按下登入按鈕),失敗原因是前面提到的預期結果與實際測試結果不同。在過去可能會在測試腳本遇到時等待一段時間再繼續 (thread.sleep n 秒),等待一段時間之後再按下按鈕,但這個 N 秒在每個環境可能會有所不同需要團隊討論,太長會影響測試腳本的執行總時間,太短則很容易遇到測試腳本執行失敗的狀況,playwright 內建 auto wait 功能讓大家可以忽略這件事情,可以更專注的撰寫重要邏輯上。


    Browser Contexts

    它能夠在單個瀏覽器中提供互相隔離的執行環境,特別是在測試多個頁面時這個特性是相當重要的,可以透過腳本很方便的實現網頁頻繁的切換。每個頁面可以在各自的 context 中執行不會互相干擾,包括 cookies 等資訊都是隔離開的。
    上述內容或許有點抽象,舉個實際的例子可能會比較好理解,假設公司產品是開發類似通訊軟體類(IM),要測試 Web 版的聊天功能,在這情境下就需要開啟兩個聊天畫面來測試聊天功能是否正常。腳本上可能是開啟兩個瀏覽器做登入,登入之後透過 A 傳給 B 看訊息內容是否有正確的送達。在過去沒有此功能可能要先登出 A 在重新登入 B 進行驗證。現在有這功能就可以省下登入登出時間快速驗證效果與功能正確性。


    Tracing
    跑測試時可能會遇到當你的測試案例執行失敗,要如何快速的定位問題,並提供給開發團隊的 RD 同仁呢 ?
    反過來說,如果可以知道在哪個步驟或是地方知道執行之敗,這樣對於盤查問題跟問題定位上會有更大的幫助,開發團隊可以更快地找到哪邊有問題,並針對有問題的地方盤查傳遞的 http request 內容或是 request body 參數是甚麼,可以更快速的找到問題並進行修正,對於修復問題的時間可以大大的提升。playwright 有提供 Trace Viewer 強大的 GUI Tools,提供截圖、action、source code 及 screenshots 等資訊讓開發人員可以定位問題,詳細可以參考 trace-viewer


    Powerful Tooling
    Test Generator : 測試團隊可能相較於開發人員,有些是比較沒有程式開發相關背景的。playwright 提供 Codegen 功能,可以透過瀏覽器錄製測試步驟,產生程式碼。程式碼可以在工具平台上重複的進行測試的動作,對於測試人員的 Loading 也相對較輕鬆。
    另外也提供測試報告,團隊可以透過測試報告來了解一些潛在的問題,舉例說當你發現測試時間過長,就可以透過測試報告觀看每一段所花費多久,找到可能可以改善的地方或是優化的點。



    Demo : Test Generator
    來透過 codegen 功能來試試看它是如何產生代馬的,在此步驟可以先開啟命令提示字元輸入安裝 playwright 指令
    npx playwright install
    
    接著輸入內建的 codegen 指令,來錄製操作步驟與產生其相關的語法
    npx playwright codegen demo.playwright.dev/todomvc
    
    會跳出瀏覽器視窗,接著可以在是窗框中輸入 keyword,在這案例中我輸入 test、this is a book,可以發現在右方框中會同步產生相關語法,如下圖所示
    你也可以錄製在 google 輸入關鍵字,接著再去點選特定的查詢結果,下面代碼是透過錄製開啟 google 首頁,接著查詢 COSCUP MEETUP 研討會連結,進入到連結後找到 "" 分享 SESSION 內容頁面,並將其結果儲存下來
    public static async Task Main()
    {
    	await GoogleCOSCUP();
    }
    
    private static async Task GoogleCOSCUP()
    {
    	using var playwright = await Playwright.CreateAsync();
    	await using var browser = await playwright.Chromium.LaunchAsync(new BrowserTypeLaunchOptions
    	{
    		Headless = false,
    	});
    	var context = await browser.NewContextAsync();
    	// Open new page
    	var page = await context.NewPageAsync();
    	// Go to https://www.google.com/?gws_rd=ssl
    	await page.GotoAsync("https://www.google.com/?gws_rd=ssl");
    	// Click [aria-label="搜尋"]
    	await page.Locator("[aria-label=\"搜尋\"]").ClickAsync();
    	// Fill [aria-label="搜尋"]
    	await page.Locator("[aria-label=\"搜尋\"]").FillAsync("coscup");
    	// Press Enter
    	await page.Locator("[aria-label=\"搜尋\"]").PressAsync("Enter");
    	//await page.WaitForURLAsync("https://www.google.com/search?q=coscup&source=hp&ei=yvHlYsjhDbmRr7wPt4OysAI&iflsig=AJiK0e8AAAAAYuX_2qYZgkQ_Hm0nRenoqQN3m5Lu5HiY&ved=0ahUKEwjI7q_lkqL5AhW5yIsBHbeBDCYQ4dUDCAo&uact=5&oq=coscup&gs_lcp=Cgdnd3Mtd2l6EAMyCwgAEIAEELEDEIMBMgQIABADMgUIABCABDIECAAQAzIECAAQAzIECAAQAzIFCAAQgAQyBQgAEIAEMgUIABCABDIFCAAQgAQ6CAgAEIAEELEDOhEILhCABBCxAxCDARDHARDRAzoOCC4QgAQQsQMQxwEQ0QM6CwguEIAEELEDEIMBOhQILhCABBCxAxCDARDHARDRAxDUAjoICAAQsQMQgwE6CwguEIAEEMcBEK8BUL4EWJcTYNIaaAJwAHgAgAGZAYgB0QWSAQM0LjOYAQCgAQGwAQA&sclient=gws-wiz");
    	// Click text=COSCUP 2022 | Conference for Open Source Coders, Users ...
    	await page.Locator("text=COSCUP 2022 | Conference for Open Source Coders, Users ...").ClickAsync();
    	await page.WaitForURLAsync("https://coscup.org/2022/zh-TW/");
    	// Click a:has-text("議程表") >> nth=1
    	await page.Locator("a:has-text(\"議程表\")").Nth(1).ClickAsync();
    	await page.WaitForURLAsync("https://coscup.org/2022/zh-TW/session");
    	// Click text=2022 / 7 / 31
    	await page.Locator("text=2022 / 7 / 31").ClickAsync();
    	// Click text=現代化 End to End 測試工具 : Playwright
    	await page.Locator("text=現代化 End to End 測試工具 : Playwright").ClickAsync();
    	await page.WaitForURLAsync("https://coscup.org/2022/zh-TW/session/3QNTQT");
    
    	await context.Tracing.StopAsync(new()
    	{
    		Path = "trace.zip"
    	});
    
    }
    
    程式說明
    • Line 9 : Headless,透過步調用瀏覽器的渲染引擎,可以提高其腳本執行速度與測試效率
    • Line 17 : 開啟 Google 首頁
    • Line 21 : 輸入 COSCUP 並按下搜尋
    • Line 26 : 點擊 COSCUP 2022 連結
    • Line 29 & 32 : 點擊議程表 & 選擇 7/31 日期
    • Line 37 : 將其結果儲存下來,檔名為 Trace.zip

    以上簡單介紹到這邊,有興趣的朋友歡迎可以試試看 :)


    感想
    如果想了解更多,可以參考 #30DaysOfPlaywright 日後有機會可以做進一步的研究跟分享,以上如果有不清楚的地方歡迎一起討論,hope it helps !

    參考
    playwright.dev

    Copyright © m@rcus 學習筆記 | Powered by Blogger

    Design by Anders Noren | Blogger Theme by NewBloggerThemes.com