On Github wojtekerbetowski / pyconpl_2014
PC + WiFi Mobile + WiFi Mobile + LTE Mobile + HSDPA+ Mobile + 2G min 0.993 2 15 42 203 avg 3.435 19 90 60 227 max 30.678 460 811 956 2000 stddev 2.22 17 x 55 84 down 139.90 18.57 14.47 5.73 0.08 up 86.19 18.23 5.73 3.68 0.1
GET /users/123
{ "name": "John Doe", "age": 25, "links": [ { "rel": "self", "href": "/users/123" }, { "rel": "account", "href": "/accounts/987" }, { "rel": "address", "href": "/addresses/555" } ] }
GET /addresses/555
{ "street": "Sesame", "no": 25, "zipCode": "12-321", "state": "NY", "country": "US" }
GET /users/123
{ "name": "John Doe", "age": 25, "country": "US" }
GET /users/123?fields=[name,age,address[country]]
{ "name": "John Doe", "age": 25, "country": "US" }
Connection: Keep-Alive
Complete model
{ "person": { "id": 12345, "firstName": "John", "lastName": "Doe", "age": 25, "phones": { "home": "800-123-4567", "work": "888-555-0000", "cell": "877-123-1234" }, "email": [ "jd@example.com", "jd@example.org" ], "dateOfBirth": "1980-01-02T00:00:00.000Z", "registered": true, "emergencyContacts": [ { "name": "", "phone": "", "email": "", "relationship": "spouse|parent|child|other" } ], "address": { "street": "Sesame", "no": 25, "zipCode": "12-321", "state": "NY", "country": "US" } } }
Trimmed model
{ "firstName": "John", "lastName": "Doe", "age": 25, "country": "US" }
Full: 222910 bytes GZIP: 32128 bytes (14%)
{ "people": [ { "firstName": "Jason", "lastName": "Page", "username": "jasonp", "isMale": true, "phone": "142-808-3743", "nid": "12252671714" }, { "firstName": "Nathaniel", "lastName": "Chaney", "username": "nchaney", "isMale": true, "phone": "481-659-731", "nid": "55122958778" }, { "firstName": "Alexis", "lastName": "Christensen", "username": "alexisc", "isMale": false, "phone": "802-046-8689", "nid": "13240667404" }, { "firstName": "Sophie", "lastName": "Duke", "username": "sophied", "isMale": false, "phone": "316-701-3331", "nid": "96071009282" }, { "firstName": "Aria", "lastName": "Wolf", "username": "ariaw", "isMale": false, "phone": "682-172-2915", "nid": "12231830224" }, { "firstName": "Sebastian", "lastName": "Hogan", "username": "sebastianh", "isMale": true, "phone": "096-033-8930", "nid": "65082565494" }, { "firstName": "Austin", "lastName": "Rice", "username": "austinr", "isMale": true, "phone": "558-871-007", "nid": "91102544132" }, { "firstName": "Elijah", "lastName": "Savage", "username": "esavage", "isMale": true, "phone": "009-900-8985", "nid": "10301742394" }, { "firstName": "Colton", "lastName": "Morris", "username": "cmorris", "isMale": true, "phone": "029-957-8223", "nid": "84062095076" }, { "firstName": "Juan", "lastName": "Bass", "username": "jbass", "isMale": true, "phone": "701-810-3457", "nid": "10311068954" }, { "firstName": "Brody", "lastName": "Reese", "username": "breese", "isMale": true, "phone": "320-610-636", "nid": "82112959596" }, { "firstName": "Stella", "lastName": "Bernard", "username": "sbernard", "isMale": false, "phone": "134-462-1924", "nid": "03272935528" }, { "firstName": "Isaac", "lastName": "Webb", "username": "iwebb", "isMale": true, "phone": "136-000-422", "nid": "10231649814" }, { "firstName": "Jackson", "lastName": "Bryan", "username": "jacksonb", "isMale": true, "phone": "629-900-7729", "nid": "83071189716" }, { "firstName": "Liam", "lastName": "Beard", "username": "lbeard", "isMale": true, "phone": "327-639-010", "nid": "86050552116" }, { "firstName": "Parker", "lastName": "Duffy", "username": "pduffy", "isMale": true, "phone": "484-829-6473", "nid": "56122687578" }, { "firstName": "Lucy", "lastName": "Moody", "username": "lucym", "isMale": false, "phone": "723-670-5321", "nid": "77051444320" }, { "firstName": "Aaliyah", "lastName": "Leonard", "username": "aleonard", "isMale": false, "phone": "005-293-048", "nid": "08281195048" }, { "firstName": "Brody", "lastName": "Norris", "username": "brodyn", "isMale": true, "phone": "789-653-2217", "nid": "58050880078" }, { "firstName": "Juan", "lastName": "Valenzuela", "username": "juanv", "isMale": true, "phone": "060-065-140", "nid": "93052612612" }, { "firstName": "Jocelyn", "lastName": "Collins", "username": "jcollins", "isMale": false, "phone": "010-257-964", "nid": "65083166064" }, { "firstName": "Bentley", "lastName": "Welch", "username": "bentleyw", "isMale": true, "phone": "068-620-269", "nid": "09293076518" } ] }
Full: 48 bytes GZIP: 60 bytes (125%)
{ "firstName": "Arianna", "lastName": "Mcknight" }
GET /people/
{ "people": [ { "firstName": "Jason", "lastName": "Page", "username": "jasonp", "isMale": true, "phone": "142-808-3743", "nid": "12252671714" }, { "firstName": "Nathaniel", "lastName": "Chaney", "username": "nchaney", "isMale": true, "phone": "481-659-731", "nid": "55122958778" }, { "firstName": "Alexis", "lastName": "Christensen", "username": "alexisc", "isMale": false, "phone": "802-046-8689", "nid": "13240667404" }, { "firstName": "Sophie", "lastName": "Duke", "username": "sophied", "isMale": false, "phone": "316-701-3331", "nid": "96071009282" }, { "firstName": "Aria", "lastName": "Wolf", "username": "ariaw", "isMale": false, "phone": "682-172-2915", "nid": "12231830224" }, { "firstName": "Sebastian", "lastName": "Hogan", "username": "sebastianh", "isMale": true, "phone": "096-033-8930", "nid": "65082565494" }, { "firstName": "Austin", "lastName": "Rice", "username": "austinr", "isMale": true, "phone": "558-871-007", "nid": "91102544132" }, { "firstName": "Elijah", "lastName": "Savage", "username": "esavage", "isMale": true, "phone": "009-900-8985", "nid": "10301742394" }, { "firstName": "Colton", "lastName": "Morris", "username": "cmorris", "isMale": true, "phone": "029-957-8223", "nid": "84062095076" }, { "firstName": "Juan", "lastName": "Bass", "username": "jbass", "isMale": true, "phone": "701-810-3457", "nid": "10311068954" }, { "firstName": "Brody", "lastName": "Reese", "username": "breese", "isMale": true, "phone": "320-610-636", "nid": "82112959596" }, { "firstName": "Stella", "lastName": "Bernard", "username": "sbernard", "isMale": false, "phone": "134-462-1924", "nid": "03272935528" }, { "firstName": "Isaac", "lastName": "Webb", "username": "iwebb", "isMale": true, "phone": "136-000-422", "nid": "10231649814" }, { "firstName": "Jackson", "lastName": "Bryan", "username": "jacksonb", "isMale": true, "phone": "629-900-7729", "nid": "83071189716" }, { "firstName": "Liam", "lastName": "Beard", "username": "lbeard", "isMale": true, "phone": "327-639-010", "nid": "86050552116" }, { "firstName": "Parker", "lastName": "Duffy", "username": "pduffy", "isMale": true, "phone": "484-829-6473", "nid": "56122687578" }, { "firstName": "Lucy", "lastName": "Moody", "username": "lucym", "isMale": false, "phone": "723-670-5321", "nid": "77051444320" }, { "firstName": "Aaliyah", "lastName": "Leonard", "username": "aleonard", "isMale": false, "phone": "005-293-048", "nid": "08281195048" }, { "firstName": "Brody", "lastName": "Norris", "username": "brodyn", "isMale": true, "phone": "789-653-2217", "nid": "58050880078" }, { "firstName": "Juan", "lastName": "Valenzuela", "username": "juanv", "isMale": true, "phone": "060-065-140", "nid": "93052612612" }, { "firstName": "Jocelyn", "lastName": "Collins", "username": "jcollins", "isMale": false, "phone": "010-257-964", "nid": "65083166064" }, { "firstName": "Bentley", "lastName": "Welch", "username": "bentleyw", "isMale": true, "phone": "068-620-269", "nid": "09293076518" } ] }
GET /people?fields=[firstName, lastName]
{ "people": [ { "firstName": "Kennedy", "lastName": "Cote" }, { "firstName": "Jocelyn", "lastName": "Parsons" }, { "firstName": "Mia", "lastName": "Key" }, { "firstName": "Jackson", "lastName": "Whitney" }, { "firstName": "Nevaeh", "lastName": "Torres" }, { "firstName": "Samuel", "lastName": "Best" }, { "firstName": "Ellie", "lastName": "Hooper" }, { "firstName": "Kevin", "lastName": "White" }, { "firstName": "Xavier", "lastName": "Wooten" }, { "firstName": "Naomi", "lastName": "Chan" }, { "firstName": "Owen", "lastName": "Ramsey" }, { "firstName": "Victoria", "lastName": "Hunter" }, { "firstName": "Harper", "lastName": "Boone" }, { "firstName": "Nicholas", "lastName": "Mcknight" }, { "firstName": "Kaylee", "lastName": "Stone" }, { "firstName": "Hudson", "lastName": "Schultz" }, { "firstName": "Thomas", "lastName": "Copeland" }, { "firstName": "Madeline", "lastName": "Odom" }, { "firstName": "Colton", "lastName": "Humphrey" }, { "firstName": "Alexis", "lastName": "Chandler" } ] }
PLAIN 171120 bytes GZIP 30855 bytes
GraysonWilkinsgraysonwtrue197-391-908739113050916NathanielPagenpagetrue922-083-806687061196536AnnabelleParksaparksfalse860-706-55010221048164CarlosRobbinscrobbinstrue633-199-364785022650976SebastianMckenziesebastianmtrue031-821-254208221481578AidenMercadoaidenmtrue413-006-955301302174138JacobTerryjacobttrue674-749-701909312515478HannahHarthhartfalse489-395-594662042618284JaxonWagnerjaxonwtrue500-770-24471081634910ChloeSanderscsandersfalse714-971-532712302121384ChristopherBrennanchristopherbtrue272-938-00506253116718LydiaMontoyalmontoyafalse106-629-31213221541804AdrianCarveracarvertrue355-762-778197111290392SamuelMcculloughsamuelmtrue382-502-58966123176094LandonGrimeslgrimestrue082-649-57510272237014IsabellaMerrillisabellamfalse795-762-425712292864824LandonDaleldaletrue959-023-13541081330132MadelineSpencemspencefalse116-600-137754070686488DamianHendersondamianhtrue091-797-81037091971136DominicHurleydominichtrue842-593-56712281078514MackenzieCoopermcooperfalse335-422-48812292859744CarsonBarnescbarnestrue649-653-77613231549814ElizabethSuttonesuttonfalse205-975-23286070205666
PLAIN 121115 bytes (70%) GZIP 29553 bytes (96%)
{ "people": [ { "firstName": "Jason", "lastName": "Page", "username": "jasonp", "isMale": true, "phone": "142-808-3743", "nid": "12252671714" }, { "firstName": "Nathaniel", "lastName": "Chaney", "username": "nchaney", "isMale": true, "phone": "481-659-731", "nid": "55122958778" }, { "firstName": "Alexis", "lastName": "Christensen", "username": "alexisc", "isMale": false, "phone": "802-046-8689", "nid": "13240667404" }, { "firstName": "Sophie", "lastName": "Duke", "username": "sophied", "isMale": false, "phone": "316-701-3331", "nid": "96071009282" }, { "firstName": "Aria", "lastName": "Wolf", "username": "ariaw", "isMale": false, "phone": "682-172-2915", "nid": "12231830224" }, { "firstName": "Sebastian", "lastName": "Hogan", "username": "sebastianh", "isMale": true, "phone": "096-033-8930", "nid": "65082565494" }, { "firstName": "Austin", "lastName": "Rice", "username": "austinr", "isMale": true, "phone": "558-871-007", "nid": "91102544132" }, { "firstName": "Elijah", "lastName": "Savage", "username": "esavage", "isMale": true, "phone": "009-900-8985", "nid": "10301742394" }, { "firstName": "Colton", "lastName": "Morris", "username": "cmorris", "isMale": true, "phone": "029-957-8223", "nid": "84062095076" }, { "firstName": "Juan", "lastName": "Bass", "username": "jbass", "isMale": true, "phone": "701-810-3457", "nid": "10311068954" }, { "firstName": "Brody", "lastName": "Reese", "username": "breese", "isMale": true, "phone": "320-610-636", "nid": "82112959596" }, { "firstName": "Stella", "lastName": "Bernard", "username": "sbernard", "isMale": false, "phone": "134-462-1924", "nid": "03272935528" }, { "firstName": "Isaac", "lastName": "Webb", "username": "iwebb", "isMale": true, "phone": "136-000-422", "nid": "10231649814" }, { "firstName": "Jackson", "lastName": "Bryan", "username": "jacksonb", "isMale": true, "phone": "629-900-7729", "nid": "83071189716" }, { "firstName": "Liam", "lastName": "Beard", "username": "lbeard", "isMale": true, "phone": "327-639-010", "nid": "86050552116" }, { "firstName": "Parker", "lastName": "Duffy", "username": "pduffy", "isMale": true, "phone": "484-829-6473", "nid": "56122687578" }, { "firstName": "Lucy", "lastName": "Moody", "username": "lucym", "isMale": false, "phone": "723-670-5321", "nid": "77051444320" }, { "firstName": "Aaliyah", "lastName": "Leonard", "username": "aleonard", "isMale": false, "phone": "005-293-048", "nid": "08281195048" }, { "firstName": "Brody", "lastName": "Norris", "username": "brodyn", "isMale": true, "phone": "789-653-2217", "nid": "58050880078" }, { "firstName": "Juan", "lastName": "Valenzuela", "username": "juanv", "isMale": true, "phone": "060-065-140", "nid": "93052612612" }, { "firstName": "Jocelyn", "lastName": "Collins", "username": "jcollins", "isMale": false, "phone": "010-257-964", "nid": "65083166064" }, { "firstName": "Bentley", "lastName": "Welch", "username": "bentleyw", "isMale": true, "phone": "068-620-269", "nid": "09293076518" } ] }
// PersonDataDownloader.m #import "PersonDataDownloader_M.h" #import "Person.h" #import "TaskCallsSynchronizer.h" @interface PersonDataDownloader_M () @property(nonatomic, strong) TaskCallsSynchronizer *synchronizer; @end @implementation PersonDataDownloader_M - (void)downloadDataForPerson:(Person *)person { self.synchronizer = [TaskCallsSynchronizer new]; self.synchronizer.completionHandler = ^(NSArray *taskDataObjects, NSArray *taskResponses) { // Merge downloaded data here and perform the rest... }; self.synchronizer.errorHandler = ^(NSArray *errors) { NSLog(@"All calls went bad..."); }; NSURLSessionDataTask *personalInfoTask = [self personalInfoTaskForPerson:person synchronizer:self.synchronizer]; NSURLSessionDataTask *accountNumberTask = [self accountNumberTaskForPerson:person synchronizer:self.synchronizer]; [self.synchronizer addTask:personalInfoTask withName:@"InfoTask"]; [self.synchronizer addTask:accountNumberTask withName:@"AccountTask"]; [personalInfoTask resume]; [accountNumberTask resume]; } #pragma mark - Tasks - (NSURLSessionDataTask *)personalInfoTaskForPerson:(Person *)person synchronizer:(TaskCallsSynchronizer *)synchronizer { NSURLSession *session = [NSURLSession sharedSession]; __typeof(synchronizer) __weak weakSynchronizer = synchronizer; NSURLSessionDataTask *personalInfoTask = [session dataTaskWithURL:[self urlForPersonsPersonalInfo:person] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { NSString *taskName = @"InfoTask"; if (data && !error) { [weakSynchronizer completeTaskWithName:taskName data:data response:response]; } else { [weakSynchronizer errorDidOccur:error forTaskWithName:taskName]; } }]; return personalInfoTask; } - (NSURLSessionDataTask *)accountNumberTaskForPerson:(Person *)person synchronizer:(TaskCallsSynchronizer *)synchronizer { NSURLSession *session = [NSURLSession sharedSession]; __typeof(synchronizer) __weak weakSynchronizer = synchronizer; NSURLSessionDataTask *accountNumberTask = [session dataTaskWithURL:[self urlForPersonsAccountNumber:person] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { NSString *taskName = @"AccountTask"; if (data && !error) { [weakSynchronizer completeTaskWithName:taskName data:data response:response]; } else { [weakSynchronizer errorDidOccur:error forTaskWithName:taskName]; } }]; return accountNumberTask; } #pragma mark - URLs - (NSURL *)urlForPersonsPersonalInfo:(Person *)person { NSString *urlString = [NSString stringWithFormat:@"http://e1.com/persons/%ld", (long)person.id]; return [[NSURL alloc] initWithString:urlString]; } - (NSURL *)urlForPersonsAccountNumber:(Person *)person { NSString *urlString = [NSString stringWithFormat:@"http://e2.com/accounts/%ld", (long)person.id]; return [[NSURL alloc] initWithString:urlString]; } @end // TaskCallSynchronizer.m #import "TaskCallsSynchronizer.h" @interface TaskCallsSynchronizer () @property(nonatomic, readonly) NSMapTable *tasksMap; @property(nonatomic, readonly) NSMutableArray *dataObjects; @property(nonatomic, readonly) NSMutableArray *responses; @property(nonatomic, readonly) NSMutableArray *errors; @property(nonatomic) BOOL errorEncountered; @end @implementation TaskCallsSynchronizer - (id)init { self = [super init]; if (self) { _tasksMap = [NSMapTable strongToWeakObjectsMapTable]; _dataObjects = [NSMutableArray array]; _responses = [NSMutableArray array]; _errors = [NSMutableArray array]; } return self; } - (void)addTask:(NSURLSessionDataTask *)task withName:(NSString *)name { [self.tasksMap setObject:task forKey:name]; } - (void)completeTaskWithName:(NSString *)name data:(NSData *)data response:(NSURLResponse *)response { @synchronized (self) { NSURLSessionDataTask *task = [self.tasksMap objectForKey:name]; BOOL isDownloadStateValid = task.state != NSURLSessionTaskStateCompleted && !self.errorEncountered; if (isDownloadStateValid) { NSLog(@"Ups, something's wrong."); } else { [self.dataObjects addObject:data]; [self.responses addObject:response]; [self.tasksMap removeObjectForKey:name]; if ([self.tasksMap count] == 0 && self.completionHandler) { self.completionHandler(self.dataObjects, self.responses); } } } } - (void)errorDidOccur:(NSError *)error forTaskWithName:(NSString *)name { @synchronized (self) { self.errorEncountered = YES; [self.errors addObject:error]; [self.tasksMap removeObjectForKey:name]; if ([self.tasksMap count] == 0 && self.errorHandler) { self.errorHandler(self.errors); } } } @end
protected void onResume() { super.onResume(); try { download(); } catch (Exception e) { Log.e(TAG, "Error while downloading data", e); } } public void download() throws ExecutionException, InterruptedException { Future<Response<JsonObject>> personFuture = Ion. with(this). load("http://e1.com/persons/123"). asJsonObject().withResponse(); Future<Response<JsonObject>> accountFuture = Ion. with(this). load("http://e2.com/accounts/456"). asJsonObject(). withResponse(); Response<JsonObject> personResponse = personFuture.get(); Response<JsonObject> accountResponse = accountFuture.get(); if (personResponse.getException() != null && accountResponse.getException() != null) { JsonObject person = personResponse.getResult().getAsJsonObject(); JsonObject account = personResponse.getResult().getAsJsonObject(); String firstName = person.getAsJsonPrimitive("firstName").toString(); String lastName = person.getAsJsonPrimitive("lastName").toString(); String accountNo = account.getAsJsonPrimitive("accountNo").toString(); } else { Log.e(TAG, "Error while downloading account", accountResponse.getException()); Log.e(TAG, "Error while downloading person", personResponse.getException()); } }
def parts = [ "http://e1.com/persons/123": ['firstName', 'lastName'], "http://e2.com/accounts/456": ['accountNo'], ] def output = withPool(2) { return parts.collectParallel({ url, fields -> def json = new JsonSlurper().parse(url as URL) return fields.collect ({ field -> ["$field": json[field]] }) }).flatten().sum() }
POST /following
{ "from": 123, "to": 456 }
POST /users/456/follow
Expires: Sat, 26 Jul 1997 05:00:00 GMT
GET /users?page=:page_number
Arthur Bob Celine Daniel Eve Fred GeorgePage size 3
Page 1: Arthur Bob Celine
Delete: Bob
Page 1: Arthur Bobby Daniel
Page 2: Eve Fred George
{ // ... "nextPage": "/users?since=5476238046501" }