“群芳爭艷”:CoreData 4 種方法計算最大值的效率比較(上)

在這里插入圖片描述

概覽

在 CoreData 支持的 App 中,一種常見操作就是計算數據庫表中指定字段的最大值(或最小值)。就是這樣一種看起來“不足掛齒”的任務,可能稍不留神就會“馬失前蹄”。
在這里插入圖片描述

在實際的代碼中,我們怎樣才能既迅速又簡潔的找出字段的最大值呢?

在本篇博文中,您將學到如下內容:

  • 概覽
  • 0. CoreData 表結構
  • 1. 借助現成的關系屬性(Relation Property)
  • 2. 使用“遠古” NSArray 的力量
  • 3. 使用 CoreData Fetch 請求
  • 總結

相信學完本課后,大家 CoreData 的算法武器庫中又會多幾種“削鐵如泥”的利刃啦。

本文中所有代碼的測試環境為:

  • MBA 2022,M2,內存 16 GB
  • macOS 15.3.2(Sequoia)

那還等什么呢?Let‘s find out!!!😉


0. CoreData 表結構

我們即將展示的所有算法都將在如下 CoreData 表結構中“施展拳腳”:

  • Project 表包含多個 VictoryStage 對象,這通過 Project 的 records 關系體現出來;
  • VictoryStage 表中包含一個類型為 Date? 的 end 字段,它用來表示 VictoryStage 的結束日期;

數據庫中被測試的特定 Project 對象里大約包含不到 400 個 VictoryStage 對象,我們要計算的就是:這些對象中 end 字段最大的值

為了方便,我們首先創建一個將集合(Set)類型 records 轉換為數組(Array)的輔助方法:

extension Project {var vstages: [VictoryStage] {if let recordAry = records?.allObjects as? [VictoryStage] {return recordAry}return []}
}

接下來,小伙伴們就可以“馳馬試劍”,恣意測試我們的算法啦!

1. 借助現成的關系屬性(Relation Property)

既然 Project 包含一對多的 vstages 關系,我們最簡單的方法是直接從此入手,找到 end 值最大(時間上最新)的那一個 VictoryStage 對象。


因為最新的 Swift Testing 框架還缺少內置的測速機制,我們只能暫時退回到 XCTest 的 measure 方法中去。這里需要提出批評,希望蘋果趕快在 Swift Testing 2 中將其補上哦。

關于更多馴服 Swift Testing 測試的小妙招,請小伙伴們移步如下鏈接觀賞精彩的內容:

  • 用接地氣的例子趣談 WWDC 24 全新的 Swift Testing 入門(一)
  • 用接地氣的例子趣談 WWDC 24 全新的 Swift Testing 入門(二)
  • 用接地氣的例子趣談 WWDC 24 全新的 Swift Testing 入門(三)
  • WWDC24(Xcode 16)中全新的 Swift Testing 使用進階
  • Xcode 16 中 Swift Testing 的參數化(Parameterized)機制趣談

算法的實現很簡單:我們只需將 vstages 數組按照 end 從新到舊排序,結果數組中第一個 VictoryStage 對象就是我們想要的。

func testPerformanceWithRelationProperty() throws {// 利用 Project 關系屬性來計算最新的 VictoryStagemeasure {let vstages = project.vstageslet mostRecent = vstages.sorted(using: SortDescriptor(\VictoryStage.end, order: .reverse)).firstprint("最新的 VStage: \(mostRecent?.end ?? Date.distantPast)")}
}

從單元測試的結果來看,10 次運行的平均耗時為:0.00464 秒。

在這里插入圖片描述

2. 使用“遠古” NSArray 的力量

我們知道,Swift 中的數組(Array)都是由底層的 Objc 數據結構 NSArray 在默默“撐腰”的。而 NSArray 又自帶了一個 sortedArray 排序方法:

在這里插入圖片描述
So,我們可以很快據此寫出 NSArray 的排序算法:

func testPerformanceWithRelationPropertyNSArray() throws {// 利用 Project 關系屬性的 NSArray 來計算最新的 VictoryStagemeasure {let vstages = project.vstageslet mostRecent = ((vstages as NSArray).sortedArray(using: [.init(keyPath: \VictoryStage.end, ascending: false)]) as! [VictoryStage]).firstprint("最新的 VStage: \(mostRecent?.end ?? Date.distantPast)")}
}

美中不足的是,這種方法需要做 2 次類型轉換。

小伙伴們可能覺得 NSArray 排序算法和前一種速度差不了多少,不過實際結果可能會讓你們大吃一驚:

在這里插入圖片描述

是的,你們沒有看錯!NSArray 排序比 Array 排序快了一個數量級,只需 0.000559 秒。

3. 使用 CoreData Fetch 請求

為了能夠充分發揮 CoreData 底層里 Sqlite 原生查詢的“奧義”,我們可以直接利用 Fetch 請求來排憂解難:

func testPerformanceWithFetchPredicate() throws {// 利用 CoreData Fetch 請求來計算最新的 VictoryStagemeasure {let req = VictoryStage.fetchRequest()req.predicate = .init(format: "project = %@", project)req.sortDescriptors = [.init(keyPath: \VictoryStage.end, ascending: false)]req.fetchLimit = 1let mostRecent = try! context.fetch(req).firstprint("最新的 VStage: \(mostRecent?.end ?? Date.distantPast)")}
}

在上面的代碼中,我們做了這樣幾件事:

  1. 創建一個 Fetch Request;
  2. 穩妥的設置了它的 Predicate 和排序屬性;
  3. 將其搜索結果的數量限制為 1 ;

運行看一下效果!恭喜大家,我們又成功的將性能提升了幾倍,現在只需 0.000196 秒了。

在這里插入圖片描述

在下一篇文章中,我們將再接再厲,使用 NSExpression 表達式方法來為本系列博文畫上一個完美的句號。


想要進一步系統地學習 Swift 開發的小伙伴們,可以來我的《Swift 語言開發精講》專欄逛一逛哦:

在這里插入圖片描述

  • 《Swift 語言開發精講》

總結

在本篇博文中,我們討論了 CoreData 中計算字段最大值的三種方法,任君選用。

感謝觀賞,我們下一篇再見!😎

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/75864.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/75864.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/75864.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

skynet網絡包庫(lua-netpack.c)的作用解析

目錄 網絡包庫(lua-netpack.c)的作用解析1. 數據包的分片與重組2. 網絡事件處理3. 內存管理4. 數據打包與解包 動態庫(.so)在 Lua 中的使用1. 編譯為動態庫2. Lua 中加載與調用(1) 加載模塊(2) 核心方法(3) 使用示例 3. 注意事項 …

計科數據庫第二次上機操作--實驗二 表的簡單查詢

一、建數據庫和表 1.啟動數據庫服務軟件 Navicat 2.在 Navicat 中建立數據庫 test 3. 在test數據庫上建立teacher表: 二、基本查詢 2.1 從teacher表中分別檢索出教師的所有信息 SELECT * FROM teacher WHERE 教工號2000; SELECT * FROM t…

WPF依賴注入

一、IOC 在 WPF 中的原理 控制反轉(IOC)是一種設計原則,它將對象的創建和依賴關系的管理從對象本身轉移到外部容器(IOC 容器)。在傳統的編程方式中,一個對象如果需要使用另一個對象(即存在依賴…

【大模型深度學習】如何估算大模型需要的顯存

一、模型參數量 參數量的單位 參數量指的是模型中所有權重和偏置的數量總和。在大模型中,參數量的單位通常以“百萬”(M)或“億”(B,也常說十億)來表示。 百萬(M):表示…

BUUCTF流量分析題

文章目錄 前言wireshark被嗅探的流量被偷走的文件easycap數據包中的線索秘密文件[安洵杯 2019]Attack (難,沒寫)被劫持的神秘禮物大流量分析(一)大流量分析(二)大流量分析(三)模板模板 前言 CT…

adb檢測不到原來的設備List of devices attached解決辦法

進設備管理器-通用串行總線設備 卸載無法檢測到的設備驅動 重新拔插數據線

mapbox基礎,加載柵格圖片到地圖

????? 主頁: gis分享者 ????? 感謝各位大佬 點贊?? 收藏? 留言?? 加關注?! ????? 收錄于專欄:mapbox 從入門到精通 文章目錄 一、??前言1.1 ??mapboxgl.Map 地圖對象1.2 ??mapboxgl.Map style屬性1.3 ??raster 柵格圖層 api二、??使用本地載…

復活之我會二分

文章目錄 整數二分模板模板1:滿足條件的第一個數模板2:滿足條件的最后一個數 浮點數二分模板一、Building an Aquarium思路分析具體代碼 二、Tracking Segments思路分析具體代碼 三、Wooden Toy Festival思路分析具體代碼 四、路標設置思路分析具體代碼 …

每日c/c++題 備戰藍橋杯(握手問題)

試題 A: 握手問題 題解 題目描述 小藍組織了一場算法交流會議,共有50人參加。按照慣例,每個人都要與除自己外的其他所有人握手一次。但有7個人彼此之間沒有握手(這7人與其他43人正常握手)。求實際發生的握手總次數。 解題思路 …

mysql8.0.29 win64下載

mysql win64安裝包 mysql win64安裝包下載 mysql win64安裝包下載 通過網盤分享的文件:mysql 鏈接: https://pan.baidu.com/s/1sEOl-wSVtOG5gfIRdt5MXw?pwdgi7i 提取碼: gi7i

browser-use開源程序使 AI 代理可以訪問網站,自動完成特定的指定任務,告訴您的計算機該做什么,它就會完成它。

一、軟件介紹 文末提供程序和源碼下載 browser-use開源程序使 AI 代理可以訪問網站,自動完成特定的指定任務,瀏覽器使用是將AI代理與瀏覽器連接的最簡單方法。告訴您的計算機該做什么,它就會完成它。 二、快速開始 使用 pip (Py…

CAD格式轉換器:Acme CAD Converter

Acme CAD Converter 是一款專業的多功能 CAD 文件管理工具,支持 ?DWG/DXF/DWF 文件查看、批量格式轉換及版本降級?,適用于工程設計、圖紙歸檔等場景?。軟件兼容 AutoCAD R2.5 至 2023 版本文件?,可輸出為 PDF、JPEG、TIFF、SVG 等 20 格式…

vmware虛擬機上Ubuntu或者其他系統無法聯網的解決方法

一、檢查虛擬機是否開啟了網絡服務 打開方式:控制面板->-管理工具--->服務 查找 VMware DHCP Service 和VMware NAT Service ,確保這兩個服務已經啟動。如下圖,沒有啟動就點擊啟動。 二、設置網絡類型 我們一般使用前兩種多一些&…

數據結構與算法:基礎與進階

🌟 各位看官好,我是maomi_9526! 🌍 種一棵樹最好是十年前,其次是現在! 🚀 今天來學習C語言的相關知識。 👍 如果覺得這篇文章有幫助,歡迎您一鍵三連,分享給更…

使用分布式鎖和樂觀鎖解決超賣問題

在電商、秒殺等高并發場景中,“超賣”問題指庫存被過量扣減,導致實際庫存不足。以下是使用 分布式鎖 和 樂觀鎖 解決超賣問題的原理與實現方案: 一、超賣問題的核心原因 多個并發請求同時讀取庫存余量,并在本地計算后發起寫操作&…

盛水最多的容器

本題有兩種解法,一種是暴力解法,直接暴力枚舉出所有的體積比較出最大的即可,但是時間復雜度達到n方。超出了限制,另一種解法就是利用單調性解法,我們著重介紹一下單調性解法。 單調性解法: 體積vh*w&…

操作系統概述(3)

批處理系統 1.單道批處理系統 單道批處理系統是成批地處理作用,并且始終只有一道作業在內存中的系統。優點:提高系統資源的利用率和系統吞吐量。缺點:系統中的資源得不到充分利用。 2.多道批處理系統 引入多道程序設計技術,是…

數字身份DID協議:如何用Solidity編寫去中心化身份合約

本文提出基于以太坊的自主主權身份(SSI)實現方案,通過擴展ERC-734/ERC-735標準構建鏈上身份核心合約,支持可驗證聲明、多密鑰輪換、屬性隱私保護等特性。設計的三層架構體系將身份控制邏輯與數據存儲分離,在測試網環境…

【目標檢測】【深度學習】【Pytorch版本】YOLOV2模型算法詳解

【目標檢測】【深度學習】【Pytorch版本】YOLOV2模型算法詳解 文章目錄 【目標檢測】【深度學習】【Pytorch版本】YOLOV2模型算法詳解前言YOLOV2的模型結構YOLOV2模型的基本執行流程YOLOV2模型的網絡參數YOLOV2模型的訓練方式 YOLOV2的核心思想前向傳播階段反向傳播階段 總結 前…

第421場周賽:數組的最大因子得分、

Q1、數組的最大因子得分 1、題目描述 給你一個整數數組 nums。 因子得分 定義為數組所有元素的最小公倍數(LCM)與最大公約數(GCD)的 乘積。 在 最多 移除一個元素的情況下,返回 nums 的 最大因子得分。 注意&…