Skip to content

Instantly share code, notes, and snippets.

@DmIvanov
Created January 12, 2019 08:49
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DmIvanov/ead75141ebb6dc24b5820f7c5e4a3749 to your computer and use it in GitHub Desktop.
Save DmIvanov/ead75141ebb6dc24b5820f7c5e4a3749 to your computer and use it in GitHub Desktop.
Serialization Benchmarks (Swift, ObjC)
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
typedef NS_ENUM(uint8_t, Gender)
{
Male,
Female
};
@interface Person : NSObject <NSCoding>
@property (nonatomic, strong) NSString *name;
@property (nonatomic, assign) NSInteger age;
@property (nonatomic, assign) Gender gender;
@property (nonatomic, strong) NSArray *friends;
@property (nonatomic, strong) NSDate *lastActiveDate;
- (NSDictionary *)encodeToDictionary;
@end
NS_ASSUME_NONNULL_END
#import "Person.h"
@implementation Person
- (instancetype)init {
self = [super init];
if (self) {
_name = @"Syd Barrett";
_age = 34;
_gender = Male;
_friends = @[
@"Nick Mason",
@"Roger Waters",
@"Richard Wright",
@"David Gilmour"
];
_lastActiveDate = [NSDate date];
}
return self;
}
- (NSDictionary *)encodeToDictionary {
return @{
@"name" : _name,
@"age" : @(_age),
@"gender" : @(_gender),
@"friends" : _friends,
@"lastActiveDate" : @"33-03-3033"
};
}
- (id)initWithCoder:(NSCoder *)decoder {
self = [super init];
if (!self) {
return nil;
}
self.name = [decoder decodeObjectForKey:@"name"];
self.age = [decoder decodeIntegerForKey:@"age"];
self.gender = [decoder decodeIntegerForKey:@"gender"];
self.friends = [decoder decodeObjectForKey:@"friends"];
self.lastActiveDate = [decoder decodeObjectForKey:@"lastActiveDate"];
return self;
}
- (void)encodeWithCoder:(NSCoder *)encoder {
[encoder encodeObject:self.name forKey:@"name"];
[encoder encodeInteger:self.age forKey:@"age"];
[encoder encodeInteger:self.gender forKey:@"gender"];
[encoder encodeObject:self.friends forKey:@"friends"];
[encoder encodeObject:self.lastActiveDate forKey:@"lastActiveDate"];
}
@end
#import <XCTest/XCTest.h>
#import "Person.h"
const NSInteger Repetitions = 10000;
@interface SerializationBenchmarkObjCTests : XCTestCase
@property (nonatomic, strong) Person *person;
@end
@implementation SerializationBenchmarkObjCTests
- (void)setUp {
_person = [Person new];
}
- (void)testJSON
{
[self measureBlock:^{
for (int i = 0; i < Repetitions; i++) {
NSDictionary *dict = [self.person encodeToDictionary];
NSData *data = [NSJSONSerialization dataWithJSONObject:dict
options:kNilOptions
error:nil];
}
}];
}
- (void)testPlist_bin
{
[self measureBlock:^{
for (int i = 0; i < Repetitions; i++) {
NSDictionary *dict = [self.person encodeToDictionary];
NSData *data = [NSPropertyListSerialization dataWithPropertyList:dict
format:NSPropertyListBinaryFormat_v1_0
options:kNilOptions
error:nil];
}
}];
}
- (void)testPlist_xml
{
[self measureBlock:^{
for (int i = 0; i < Repetitions; i++) {
NSDictionary *dict = [self.person encodeToDictionary];
NSData *data = [NSPropertyListSerialization dataWithPropertyList:dict
format:NSPropertyListXMLFormat_v1_0
options:kNilOptions
error:nil];
}
}];
}
- (void)testArchiver_bin
{
[self measureBlock:^{
for (int i = 0; i < Repetitions; i++) {
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initRequiringSecureCoding:NO];
archiver.outputFormat = NSPropertyListBinaryFormat_v1_0;
[archiver encodeRootObject:self.person];
NSData *data = [archiver encodedData];
}
}];
}
- (void)testArchiver_xml
{
[self measureBlock:^{
for (int i = 0; i < Repetitions; i++) {
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initRequiringSecureCoding:NO];
archiver.outputFormat = NSPropertyListBinaryFormat_v1_0;
[archiver encodeRootObject:self.person];
NSData *data = [archiver encodedData];
}
}];
}
@end
import XCTest
enum Gender: String, Codable {
case male, female
}
struct Person: Codable {
let name = "Syd Barrett"
let age = 34
let gender = Gender.male
let friends: [String] = [
"Nick Mason",
"Roger Waters",
"Richard Wright",
"David Gilmour"
]
let lastActiveDate = Date()
}
class SerializationBenchmarkTests: XCTestCase {
let repetitions = 10000
var person: Person!
override func setUp() {
person = Person()
}
func testJSON() {
self.measure {
for _ in 0...repetitions {
let _ = try? JSONEncoder().encode(person)
}
}
}
func testPlist_bin() {
self.measure {
for _ in 0...repetitions {
let encoder = PropertyListEncoder()
encoder.outputFormat = .binary
let _ = try? encoder.encode(person)
}
}
}
func testPlist_xml() {
self.measure {
for _ in 0...repetitions {
let encoder = PropertyListEncoder()
encoder.outputFormat = .xml
let _ = try? encoder.encode(person)
}
}
}
func testArchiver_bin() {
self.measure {
for _ in 0...repetitions {
let archiever = NSKeyedArchiver(requiringSecureCoding: false)
archiever.outputFormat = .binary
try? archiever.encodeEncodable(person, forKey: NSKeyedArchiveRootObjectKey)
archiever.finishEncoding()
}
}
}
func testArchiver_xml() {
self.measure {
for _ in 0...repetitions {
let archiever = NSKeyedArchiver(requiringSecureCoding: false)
archiever.outputFormat = .xml
try? archiever.encodeEncodable(person, forKey: NSKeyedArchiveRootObjectKey)
archiever.finishEncoding()
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment