- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
AppKit 中有没有一种方法可以非常快速地测量大量 NSString 对象(比如一百万个)的宽度?我已经尝试了 3 种不同的方法来做到这一点:
Count\Mechanism sizeWithAttributes NSAttributedString NSLayoutManager
1000 0.057 0.031 0.007
10000 0.329 0.325 0.064
100000 3.06 3.14 0.689
1000000 29.5 31.3 7.06
NSLayoutManager 显然是要走的路,但问题是
如果你想玩,Here是github项目。
最佳答案
这里有一些我没有尝试过的想法。
使用 Core Text直接地。其他 API 都建立在它之上。
并行化。所有现代 Mac(甚至所有现代 iOS 设备)都有多个内核。将字符串数组分成几个子数组。对于每个子数组,将一个 block 提交到 global GCD queue .在 block 中,创建必要的 Core Text 或 NSLayoutManager
对象并测量子数组中的字符串。可以通过这种方式安全地使用这两个 API。 (Core Text) (NSLayoutManager
)
关于“高内存占用”:Use Local Autorelease Pool Blocks to Reduce Peak Memory Footprint.
关于“所有时间都花在创建上述字符串的过程中,这本身就是一个破坏因素”:您是说所有时间都花在这些行上:
double random = (double)arc4random_uniform(1000) / 1000;
NSString *randomNumber = [NSString stringWithFormat:@"%f", random];
格式化一个 float 是很昂贵的。这是您的真实用例吗?如果您只想为 0 ≤ n < 1000 格式化 n/1000 形式的随机有理数,则有更快的方法。此外,在许多字体中,所有数字都具有相同的宽度,因此很容易排版数字列。如果你选择这样的字体,你可以避免首先测量字符串。
这是我使用 Core Text 编写的最快的代码。在我的 Core i7 MacBook Pro 上,调度版本的速度几乎是单线程版本的两倍。我的项目分支是 here .
static CGFloat maxWidthOfStringsUsingCTFramesetter(
NSArray *strings, NSRange range) {
NSString *bigString =
[[strings subarrayWithRange:range] componentsJoinedByString:@"\n"];
NSAttributedString *richText =
[[NSAttributedString alloc]
initWithString:bigString
attributes:@{ NSFontAttributeName: (__bridge NSFont *)font }];
CGPathRef path =
CGPathCreateWithRect(CGRectMake(0, 0, CGFLOAT_MAX, CGFLOAT_MAX), NULL);
CGFloat width = 0.0;
CTFramesetterRef setter =
CTFramesetterCreateWithAttributedString(
(__bridge CFAttributedStringRef)richText);
CTFrameRef frame =
CTFramesetterCreateFrame(
setter, CFRangeMake(0, bigString.length), path, NULL);
NSArray *lines = (__bridge NSArray *)CTFrameGetLines(frame);
for (id item in lines) {
CTLineRef line = (__bridge CTLineRef)item;
width = MAX(width, CTLineGetTypographicBounds(line, NULL, NULL, NULL));
}
CFRelease(frame);
CFRelease(setter);
CFRelease(path);
return (CGFloat)width;
}
static void test_CTFramesetter() {
runTest(__func__, ^{
return maxWidthOfStringsUsingCTFramesetter(
testStrings, NSMakeRange(0, testStrings.count));
});
}
static void test_CTFramesetter_dispatched() {
runTest(__func__, ^{
dispatch_queue_t gatherQueue = dispatch_queue_create(
"test_CTFramesetter_dispatched result-gathering queue", nil);
dispatch_queue_t runQueue =
dispatch_get_global_queue(QOS_CLASS_UTILITY, 0);
dispatch_group_t group = dispatch_group_create();
__block CGFloat gatheredWidth = 0.0;
const size_t Parallelism = 16;
const size_t totalCount = testStrings.count;
// Force unsigned long to get 64-bit math to avoid overflow for
// large totalCounts.
for (unsigned long i = 0; i < Parallelism; ++i) {
NSUInteger start = (totalCount * i) / Parallelism;
NSUInteger end = (totalCount * (i + 1)) / Parallelism;
NSRange range = NSMakeRange(start, end - start);
dispatch_group_async(group, runQueue, ^{
double width =
maxWidthOfStringsUsingCTFramesetter(testStrings, range);
dispatch_sync(gatherQueue, ^{
gatheredWidth = MAX(gatheredWidth, width);
});
});
}
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
return gatheredWidth;
});
}
关于objective-c - 在 AppKit 中测量文本宽度的性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30537811/
性能优化的重要性不言而喻,Google 的 研究表明 ,当网站达到核心 Web 指标(Core Web Vitals)阈值时,用户放弃加载网页的可能性会降低 24%。 如何
我正在创建一个横幅设计创建器(这样人们就可以使用自己的文本、背景、图像、形状等来制作自己的设计)。我的产品有各种尺寸,例如:800x2000 mm、A4(210 x 297mm)、3300x2200m
我不确定如何使用测量来获取单位的全名。例如“公里”而不是“公里”。 let measurement = Measurement(value: 50, unit: UnitLength.meters)
我有一个自定义 ViewGroup,它有一个子 ViewPager。 ViewPager 由 PagerAdapter 提供,该 LinearLayout 向 ViewPager 提供 LayoutP
我想测量一个大型软件项目在 Linux (make) 中构建过程中的内存消耗是多少内存。理想情况下,消耗会按操作(即编译、链接)拆分,但一开始绘制随时间变化的图表可能就足够了。 我有哪些选择? 最佳答
我正在运行一个 SSIS 包来从一个平面文件加载一百万行,它使用一个脚本任务进行复杂的转换和一个 SQL Server 表目标。我试图找出在数据流处理期间将行数(可能是 1000 的倍数以提高效率)写
我正在尝试检查 Keras 模型不同层的执行速度(使用来自 tensorflow 2.3.0 v 的 keras) 我从这个 repo 中获取了代码并修改它,使用 timer() from from
我有一个旧的应用程序,一个 JAR 文件,它经过了一些增强。基本上必须修改代码的某些部分以及修改一些逻辑。 将旧版本与新版本进行比较,新版本比旧版本慢约 2 倍。 我试图缩小导致速度变慢的原因,但我发
我正在尝试测量不同 Silverlight 图表库(例如 Silverlight Control Toolkit、Visifire、Telerik)在屏幕上加载所需的时间。 我的问题是我只能测量加载控
由于 TTFB 会因每个请求而异,因此我想对其进行统计并获取平均值。有谁知道我如何通过 PHP 进行测量?bytecheck.com 网站能够分析这些数据:这是 example.com 的示例:htt
我正在使用 .NET 4.0 C# 编写应用程序。我将对象放在 .net httpruntime 缓存中,并希望在其上生成一些统计信息。我想知道对象在放入缓存之前的大小以及它在缓存中的大小。我该如何衡
我正在寻找某种方法来测量应用程序的启动时间。从点击应用程序图标的那一刻到用户可以看到例如登录页面的那一刻。 最佳答案 跑 flutter run --trace-startup --profile 跟
我正在优化 iPhone 应用程序以实现非常短的加载时间,我想知道: 是否有一种方法可以测量 iPhone 应用程序从用户点击图标到应用程序可用(或至少 –viewDidLoad 被调用)的加载时间?
我无法理解 中的一件事谷歌分析 .我的应用中需要一个功能,例如 一个 用户将我的应用转至 乙用户然后他得到了一些奖励,但我想跟踪 一个 时通过链接的用户 ID乙用户点击该链接然后我可以得到一个 中的用
有没有办法用 DUnit 来衡量代码覆盖率?或者有没有免费的工具可以实现这一点?你用它做什么?您通常追求什么代码覆盖率? Jim McKeeth:感谢您的详细回答。我谈论的是 TDD 方法意义上的单元
当我执行Makefile时,是否可以递归地回荡在make all的每个目标中花费的(系统,用户,实际)时间? 我想以比time make all更细粒度的方式对项目的编译进行基准测试。理想情况下,它将
R 中有衡量函数执行时间的标准化方法吗? 显然我可以在执行之前和之后获取system.time,然后取它们的差异,但我想知道是否有一些标准化的方法或功能(不想发明轮)。 我似乎记得我曾经使用过如下的东
我最近为了好玩而开始学习 Fortran,我想知道是否有任何简单的方法来显示执行我的代码所花费的时间。这只是一个数到一百万的简单循环,我想看看完成这个需要多长时间。 如果有帮助,这是我正在使用的代码:
我正在开发一个 Shiny 的应用程序。 我对计算执行某些代码块(例如 ggplot 等)所需的时间很感兴趣。 出于某种原因,使用通常的时钟方法似乎在响应式(Reactive)调用中不起作用,例如:
我想测量 jpeg 的白色/黄色量(在可调整的容差范围内)。 我正在尝试开发一种质量控制工具来测量杏仁的缺陷。缺陷是棕色杏仁皮上的划痕(见下图)。由于这些缺陷是白色/黄色的,我想要一种简单地将图像加载
我是一名优秀的程序员,十分优秀!