What is the difference between the benchmarks for the following actions when optimizing?
In addition,
in terms of time differences, benchmark differences, and ease of reading, etc.
Which code is better?
-(NSNumber*)sum:(NSArray*) items{
NSIntegersum = 0;
for (NSNumber* number in menuItemComponents) {
sum+=number.integerValue;
}
return [NSNumberWithInteger:sum];
}
- (NSNumber*) sum: (NSArray*) items {
NSNumber*sum = [NSNumber numberWithInteger:0];
for (NSNumber* number items) {
sum = [NSNumber numberWithInteger: sum.integerValue + number.integerValue];
}
return sum;
}
XCUnitTest
in Xcode
measured the execution time of the source that appears to be almost equivalent.
If the number of items
is small, it will be difficult to make a significant difference, so I have decided to make it an extreme number of items.
#import<XCTest/XCTest.h>
@ interface SpeedTestTests—XCTestCase
@end
@implementation SpeedTestTests
- (void)setUp{
// Put setup code here. This method is called before the invocation of each test method in the class.
}
- (void) tearDown {
// Put teardown code here. This method is called after the invocation of each test method in the class.
}
- (void) testExample {
// This is an example of a functional test case.
// Use XCTAssert and related functions to verify your tests produce the correct results.
}
- (void) testPerformanceNumeric {
NSArray<NSNumber *> *items = @[@1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10];
[self measureBlock:^{
NSIntegersum = 0;
for (NSNumber* number items) {
sum+=number.integerValue;
}
}];
}
- (void) testPerformanceObject {
NSArray<NSNumber *> *items = @[@1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10];
[self measureBlock:^{
NSNumber*sum = [NSNumber numberWithInteger:0];
for (NSNumber* number items) {
sum = [NSNumber numberWithInteger: sum.integerValue + number.integerValue];
}
}];
}
@end
The result is
[SpeedTestTests testPerformanceNumeric] 'measured [Time, seconds] average: 0.000, relative standard deviation: 20.883%, values: [0.000009, 0.000006, 0.000005, 0.000008, 0.000005, 0.000005, 0.000005, 0.000005, 0.000005, 0.000005], performanceMetricID:com.apple.XCTPerformanceMetric_WallClockTime, baselineName: "", baselineAverage: , maxPercentRegression: 10.000%, maxPercentRelativeStandardDeviation: 10.000%, maxRegression: 0.100, maxStandardDeviation —0.100
SpeedTestTests testPerformanceObject 'measured [Time, seconds] average: 0.000, relative standard deviation: 5.197%, values: [0.000014, 0.000012, 0.000012, 0.000012, 0.000012, 0.000012, 0.000012, 0.000012, 0.000012, 0.000012], performanceMetricID:com.apple.XCTPerformanceMetric_WallClockTime, baselineName: "", baselineAverage: , maxPercentRegression: 10.000%, maxPercentRelativeStandardDeviation: 10.000%, maxRegression: 0.100, maxStandardDevibration —0.100
On average, it seems that the latter is twice as late.
As for readability, I think the former is easy to understand that the integer value of the instance is added up and returned as an instance, so isn't the former sufficient?
But if we look through the whole program, is this really a bottleneck?
As a trend, program bottlenecks are often less than 10% of the total source code, so only if the speed is not sufficient should you look for the entire program bottleneck in TimeProfiler
and tune it speed-first if necessary.
I'm so conscious of the speed that I write a difficult code, and I think it's putting the cart before the horse when it comes to bugs.Be aware that it is easy to read even if it becomes redundant, and leave the rest to the compiler optimization.If necessary, the UnitTest
of Xcode
also has time measurements, so it might be a good idea to use it like this.
© 2024 OneMinuteCode. All rights reserved.