I am developing an iOS app in which the user enters their mobile number. How do I get their country calling code? For example, if a user is in India, then +91 should be prefixed automatically. Is there an option that adds country codes automatically?
Import Statement :
#import<CoreTelephony/CTCarrier.h>
#import <CoreTelephony/CTTelephonyNetworkInfo.h>
you can get country code for the current Carrier using CoreTelephony framework:
CTTelephonyNetworkInfo *network_Info = [CTTelephonyNetworkInfo new];
CTCarrier *carrier = network_Info.subscriberCellularProvider;
NSLog(#"country code is: %#", carrier.mobileCountryCode);
//will return the actual country code
NSLog(#"ISO country code is: %#", carrier.isoCountryCode);
Apple Docs
with the use of NSLocale you can get the country name, code etc. Take a look at below code it will help you to do so.
NSLocale *currentLocale = [NSLocale currentLocale]; // get the current locale.
NSString *countryCode = [currentLocale objectForKey:NSLocaleCountryCode]; // get country code, e.g. ES (Spain), FR (France), etc.
for a countries dialing code you can visit this reference code.
Use this simple function
func getCountryCallingCode(countryRegionCode:String)->String{
let prefixCodes = ["AF": "93", "AE": "971", "AL": "355", "AN": "599", "AS":"1", "AD": "376", "AO": "244", "AI": "1", "AG":"1", "AR": "54","AM": "374", "AW": "297", "AU":"61", "AT": "43","AZ": "994", "BS": "1", "BH":"973", "BF": "226","BI": "257", "BD": "880", "BB": "1", "BY": "375", "BE":"32","BZ": "501", "BJ": "229", "BM": "1", "BT":"975", "BA": "387", "BW": "267", "BR": "55", "BG": "359", "BO": "591", "BL": "590", "BN": "673", "CC": "61", "CD":"243","CI": "225", "KH":"855", "CM": "237", "CA": "1", "CV": "238", "KY":"345", "CF":"236", "CH": "41", "CL": "56", "CN":"86","CX": "61", "CO": "57", "KM": "269", "CG":"242", "CK": "682", "CR": "506", "CU":"53", "CY":"537","CZ": "420", "DE": "49", "DK": "45", "DJ":"253", "DM": "1", "DO": "1", "DZ": "213", "EC": "593", "EG":"20", "ER": "291", "EE":"372","ES": "34", "ET": "251", "FM": "691", "FK": "500", "FO": "298", "FJ": "679", "FI":"358", "FR": "33", "GB":"44", "GF": "594", "GA":"241", "GS": "500", "GM":"220", "GE":"995","GH":"233", "GI": "350", "GQ": "240", "GR": "30", "GG": "44", "GL": "299", "GD":"1", "GP": "590", "GU": "1", "GT": "502", "GN":"224","GW": "245", "GY": "595", "HT": "509", "HR": "385", "HN":"504", "HU": "36", "HK": "852", "IR": "98", "IM": "44", "IL": "972", "IO":"246", "IS": "354", "IN": "91", "ID":"62", "IQ":"964", "IE": "353","IT":"39", "JM":"1", "JP": "81", "JO": "962", "JE":"44", "KP": "850", "KR": "82","KZ":"77", "KE": "254", "KI": "686", "KW": "965", "KG":"996","KN":"1", "LC": "1", "LV": "371", "LB": "961", "LK":"94", "LS": "266", "LR":"231", "LI": "423", "LT": "370", "LU": "352", "LA": "856", "LY":"218", "MO": "853", "MK": "389", "MG":"261", "MW": "265", "MY": "60","MV": "960", "ML":"223", "MT": "356", "MH": "692", "MQ": "596", "MR":"222", "MU": "230", "MX": "52","MC": "377", "MN": "976", "ME": "382", "MP": "1", "MS": "1", "MA":"212", "MM": "95", "MF": "590", "MD":"373", "MZ": "258", "NA":"264", "NR":"674", "NP":"977", "NL": "31","NC": "687", "NZ":"64", "NI": "505", "NE": "227", "NG": "234", "NU":"683", "NF": "672", "NO": "47","OM": "968", "PK": "92", "PM": "508", "PW": "680", "PF": "689", "PA": "507", "PG":"675", "PY": "595", "PE": "51", "PH": "63", "PL":"48", "PN": "872","PT": "351", "PR": "1","PS": "970", "QA": "974", "RO":"40", "RE":"262", "RS": "381", "RU": "7", "RW": "250", "SM": "378", "SA":"966", "SN": "221", "SC": "248", "SL":"232","SG": "65", "SK": "421", "SI": "386", "SB":"677", "SH": "290", "SD": "249", "SR": "597","SZ": "268", "SE":"46", "SV": "503", "ST": "239","SO": "252", "SJ": "47", "SY":"963", "TW": "886", "TZ": "255", "TL": "670", "TD": "235", "TJ": "992", "TH": "66", "TG":"228", "TK": "690", "TO": "676", "TT": "1", "TN":"216","TR": "90", "TM": "993", "TC": "1", "TV":"688", "UG": "256", "UA": "380", "US": "1", "UY": "598","UZ": "998", "VA":"379", "VE":"58", "VN": "84", "VG": "1", "VI": "1","VC":"1", "VU":"678", "WS": "685", "WF": "681", "YE": "967", "YT": "262","ZA": "27" , "ZM": "260", "ZW":"263"]
let countryDialingCode = prefixCodes[countryRegionCode]
return countryDialingCode!
}
And call as
let currentLocale = NSLocale.currentLocale()
let countryCode = currentLocale.objectForKey(NSLocaleCountryCode) as! String//get the set country name, code of your iphone
print("country code is \(countryCode)")
print(getCountryCallingCode(countryCode))
//change country region Settings>>General>>Language&Region>>Region
Swift
let networkInfo = CTTelephonyNetworkInfo()
if let carrier = networkInfo.subscriberCellularProvider {
print("country code is: " + carrier.mobileCountryCode!);
//will return the actual country code
print("ISO country code is: " + carrier.isoCountryCode!);
}
Swift 5
I combine answer from Oded and LC into a function.
func getCountryCode() -> String {
guard let carrier = CTTelephonyNetworkInfo().subscriberCellularProvider, let countryCode = carrier.isoCountryCode else { return "" }
let prefixCodes = ["AF": "93", "AE": "971", "AL": "355", "AN": "599", "AS":"1", "AD": "376", "AO": "244", "AI": "1", "AG":"1", "AR": "54","AM": "374", "AW": "297", "AU":"61", "AT": "43","AZ": "994", "BS": "1", "BH":"973", "BF": "226","BI": "257", "BD": "880", "BB": "1", "BY": "375", "BE":"32","BZ": "501", "BJ": "229", "BM": "1", "BT":"975", "BA": "387", "BW": "267", "BR": "55", "BG": "359", "BO": "591", "BL": "590", "BN": "673", "CC": "61", "CD":"243","CI": "225", "KH":"855", "CM": "237", "CA": "1", "CV": "238", "KY":"345", "CF":"236", "CH": "41", "CL": "56", "CN":"86","CX": "61", "CO": "57", "KM": "269", "CG":"242", "CK": "682", "CR": "506", "CU":"53", "CY":"537","CZ": "420", "DE": "49", "DK": "45", "DJ":"253", "DM": "1", "DO": "1", "DZ": "213", "EC": "593", "EG":"20", "ER": "291", "EE":"372","ES": "34", "ET": "251", "FM": "691", "FK": "500", "FO": "298", "FJ": "679", "FI":"358", "FR": "33", "GB":"44", "GF": "594", "GA":"241", "GS": "500", "GM":"220", "GE":"995","GH":"233", "GI": "350", "GQ": "240", "GR": "30", "GG": "44", "GL": "299", "GD":"1", "GP": "590", "GU": "1", "GT": "502", "GN":"224","GW": "245", "GY": "595", "HT": "509", "HR": "385", "HN":"504", "HU": "36", "HK": "852", "IR": "98", "IM": "44", "IL": "972", "IO":"246", "IS": "354", "IN": "91", "ID":"62", "IQ":"964", "IE": "353","IT":"39", "JM":"1", "JP": "81", "JO": "962", "JE":"44", "KP": "850", "KR": "82","KZ":"77", "KE": "254", "KI": "686", "KW": "965", "KG":"996","KN":"1", "LC": "1", "LV": "371", "LB": "961", "LK":"94", "LS": "266", "LR":"231", "LI": "423", "LT": "370", "LU": "352", "LA": "856", "LY":"218", "MO": "853", "MK": "389", "MG":"261", "MW": "265", "MY": "60","MV": "960", "ML":"223", "MT": "356", "MH": "692", "MQ": "596", "MR":"222", "MU": "230", "MX": "52","MC": "377", "MN": "976", "ME": "382", "MP": "1", "MS": "1", "MA":"212", "MM": "95", "MF": "590", "MD":"373", "MZ": "258", "NA":"264", "NR":"674", "NP":"977", "NL": "31","NC": "687", "NZ":"64", "NI": "505", "NE": "227", "NG": "234", "NU":"683", "NF": "672", "NO": "47","OM": "968", "PK": "92", "PM": "508", "PW": "680", "PF": "689", "PA": "507", "PG":"675", "PY": "595", "PE": "51", "PH": "63", "PL":"48", "PN": "872","PT": "351", "PR": "1","PS": "970", "QA": "974", "RO":"40", "RE":"262", "RS": "381", "RU": "7", "RW": "250", "SM": "378", "SA":"966", "SN": "221", "SC": "248", "SL":"232","SG": "65", "SK": "421", "SI": "386", "SB":"677", "SH": "290", "SD": "249", "SR": "597","SZ": "268", "SE":"46", "SV": "503", "ST": "239","SO": "252", "SJ": "47", "SY":"963", "TW": "886", "TZ": "255", "TL": "670", "TD": "235", "TJ": "992", "TH": "66", "TG":"228", "TK": "690", "TO": "676", "TT": "1", "TN":"216","TR": "90", "TM": "993", "TC": "1", "TV":"688", "UG": "256", "UA": "380", "US": "1", "UY": "598","UZ": "998", "VA":"379", "VE":"58", "VN": "84", "VG": "1", "VI": "1","VC":"1", "VU":"678", "WS": "685", "WF": "681", "YE": "967", "YT": "262","ZA": "27" , "ZM": "260", "ZW":"263"]
let countryDialingCode = prefixCodes[countryCode.uppercased()] ?? ""
return countryDialingCode
}
Make sure to import CoreTelephony at the top
import CoreTelephony
I think you need to use NSLocale for using Country code of the user.
You can follow this link to understand use of NSLocale class reference.
Also study this link for ISOCountryCode property.
Hope this may help you.
I came up with the following code, based on previous answers:
Swift
#if canImport(CoreTelephony)
import CoreTelephony
#endif
static func getRegionCodeFromSim() -> String? {
#if canImport(CoreTelephony)
let networkInfos = CTTelephonyNetworkInfo()
if #available(iOS 12, *) {
let carrier = networkInfos.serviceSubscriberCellularProviders?
.map { $0.1 }
.first { $0.isoCountryCode != nil }
return carrier?.isoCountryCode
}
return networkInfos.subscriberCellularProvider?.isoCountryCode
#else
return nil
#endif
}
static func getRegionCode() -> String? {
guard let regionCodeFromSim = Self.getRegionCodeFromSim() else {
return NSLocale.current.regionCode
}
return regionCodeFromSim
}
static func getCountryCode() -> String? {
guard let regionCode = Self.getRegionCode() else { return nil }
let prefixCodes = ["AF": "93", "AE": "971", "AL": "355", "AN": "599", "AS":"1", "AD": "376", "AO": "244", "AI": "1", "AG":"1", "AR": "54","AM": "374", "AW": "297", "AU":"61", "AT": "43","AZ": "994", "BS": "1", "BH":"973", "BF": "226","BI": "257", "BD": "880", "BB": "1", "BY": "375", "BE":"32","BZ": "501", "BJ": "229", "BM": "1", "BT":"975", "BA": "387", "BW": "267", "BR": "55", "BG": "359", "BO": "591", "BL": "590", "BN": "673", "CC": "61", "CD":"243","CI": "225", "KH":"855", "CM": "237", "CA": "1", "CV": "238", "KY":"345", "CF":"236", "CH": "41", "CL": "56", "CN":"86","CX": "61", "CO": "57", "KM": "269", "CG":"242", "CK": "682", "CR": "506", "CU":"53", "CY":"537","CZ": "420", "DE": "49", "DK": "45", "DJ":"253", "DM": "1", "DO": "1", "DZ": "213", "EC": "593", "EG":"20", "ER": "291", "EE":"372","ES": "34", "ET": "251", "FM": "691", "FK": "500", "FO": "298", "FJ": "679", "FI":"358", "FR": "33", "GB":"44", "GF": "594", "GA":"241", "GS": "500", "GM":"220", "GE":"995","GH":"233", "GI": "350", "GQ": "240", "GR": "30", "GG": "44", "GL": "299", "GD":"1", "GP": "590", "GU": "1", "GT": "502", "GN":"224","GW": "245", "GY": "595", "HT": "509", "HR": "385", "HN":"504", "HU": "36", "HK": "852", "IR": "98", "IM": "44", "IL": "972", "IO":"246", "IS": "354", "IN": "91", "ID":"62", "IQ":"964", "IE": "353","IT":"39", "JM":"1", "JP": "81", "JO": "962", "JE":"44", "KP": "850", "KR": "82","KZ":"77", "KE": "254", "KI": "686", "KW": "965", "KG":"996","KN":"1", "LC": "1", "LV": "371", "LB": "961", "LK":"94", "LS": "266", "LR":"231", "LI": "423", "LT": "370", "LU": "352", "LA": "856", "LY":"218", "MO": "853", "MK": "389", "MG":"261", "MW": "265", "MY": "60","MV": "960", "ML":"223", "MT": "356", "MH": "692", "MQ": "596", "MR":"222", "MU": "230", "MX": "52","MC": "377", "MN": "976", "ME": "382", "MP": "1", "MS": "1", "MA":"212", "MM": "95", "MF": "590", "MD":"373", "MZ": "258", "NA":"264", "NR":"674", "NP":"977", "NL": "31","NC": "687", "NZ":"64", "NI": "505", "NE": "227", "NG": "234", "NU":"683", "NF": "672", "NO": "47","OM": "968", "PK": "92", "PM": "508", "PW": "680", "PF": "689", "PA": "507", "PG":"675", "PY": "595", "PE": "51", "PH": "63", "PL":"48", "PN": "872","PT": "351", "PR": "1","PS": "970", "QA": "974", "RO":"40", "RE":"262", "RS": "381", "RU": "7", "RW": "250", "SM": "378", "SA":"966", "SN": "221", "SC": "248", "SL":"232","SG": "65", "SK": "421", "SI": "386", "SB":"677", "SH": "290", "SD": "249", "SR": "597","SZ": "268", "SE":"46", "SV": "503", "ST": "239","SO": "252", "SJ": "47", "SY":"963", "TW": "886", "TZ": "255", "TL": "670", "TD": "235", "TJ": "992", "TH": "66", "TG":"228", "TK": "690", "TO": "676", "TT": "1", "TN":"216","TR": "90", "TM": "993", "TC": "1", "TV":"688", "UG": "256", "UA": "380", "US": "1", "UY": "598","UZ": "998", "VA":"379", "VE":"58", "VN": "84", "VG": "1", "VI": "1","VC":"1", "VU":"678", "WS": "685", "WF": "681", "YE": "967", "YT": "262","ZA": "27" , "ZM": "260", "ZW":"263"]
return prefixCodes[regionCode.uppercased()]
}
It tries to fetch the country code from the SIM cards (with multi-sim & non-sim devices support), if available, and fallbacks to the device's locale otherwise.
The prefixCodes could be loaded from a PLIST or JSON to help with readability.
If you want to prefixed calling country code automatically
then you need to get user's country code pragmatically and Drag & drop src Folder in your code
Its looks like this:
if let countryCode = (Locale.current as NSLocale).object(forKey: .countryCode) as? String {
print(countryCode)
let strCode = Countries.countryFromCountryCode(countryCode: countryCode)
btnPhoneCode.setTitle("+\(strCode.phoneExtension)", for: .normal)
}
It works for me, Hope will help you too. :)
NSLocale *currentLocale = [NSLocale currentLocale]; // get the current locale.
NSString *countryCode = [currentLocale objectForKey:NSLocaleCountryCode];
// get country code, e.g. ES (Spain), FR (France), etc.
NSLog(#"country code is:%#",countryCode);
NSString*lower=[countryCode lowercaseString];
NSString *path = [[NSBundle mainBundle] pathForResource:#"DiallingCodes" ofType:#"plist"];
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:path];
NSMutableDictionary *_dictCountry=[[NSMutableDictionary alloc]init];
NSMutableArray *_CodeArray=[[NSMutableArray alloc]init];
[_CodeArray addObject:dict];
_dictCountry = [_CodeArray objectAtIndex:0];
NSString*Country_code=[NSString stringWithFormat:#"+%#",[_dictCountry objectForKey:lower]];
contactTextField.text=Country_code;
You can request to this url.
For get CountryCode or ip, region_name, city, long, lat
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:#"http://freegeoip.net/json/"]];
__block NSDictionary *json;
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
NSLog(#"Countrycode: %#", json[#"country_code"]);
}];
Here the Objective C code
#import<CoreTelephony/CTCarrier.h>
#import <CoreTelephony/CTTelephonyNetworkInfo.h>
- (void)viewDidLoad{
CTTelephonyNetworkInfo *network_Info = [CTTelephonyNetworkInfo new];
CTCarrier *carrier = network_Info.subscriberCellularProvider;
NSLog(#"country code is: %#", carrier.mobileCountryCode);
NSLog(#"ISO country code is: %#", carrier.mobileNetworkCode);
NSLog(#"diling code == %#",[self getCountryCode:carrier.isoCountryCode]);
}
- (NSString *)getCountryCode:(NSString *)countryISOCode{
NSDictionary * code = #{#"AF": #"93", #"AE": #"971", #"AL": #"355", #"AN": #"599", #"AS":#"1", #"AD": #"376", #"AO": #"244", #"AI": #"1", #"AG":#"1", #"AR": #"54",#"AM": #"374", #"AW": #"297", #"AU":#"61", #"AT": #"43",#"AZ": #"994", #"BS": #"1", #"BH":#"973", #"BF": #"226",#"BI": #"257", #"BD": #"880", #"BB": #"1", #"BY": #"375", #"BE":#"32",#"BZ": #"501", #"BJ": #"229", #"BM": #"1", #"BT":#"975", #"BA": #"387", #"BW": #"267", #"BR": #"55", #"BG": #"359", #"BO": #"591", #"BL": #"590", #"BN": #"673", #"CC": #"61", #"CD":#"243",#"CI": #"225", #"KH":#"855", #"CM": #"237", #"CA": #"1", #"CV": #"238", #"KY":#"345", #"CF":#"236", #"CH": #"41", #"CL": #"56", #"CN":#"86",#"CX": #"61", #"CO": #"57", #"KM": #"269", #"CG":#"242", #"CK": #"682", #"CR": #"506", #"CU":#"53", #"CY":#"537",#"CZ": #"420", #"DE": #"49", #"DK": #"45", #"DJ":#"253", #"DM": #"1", #"DO": #"1", #"DZ": #"213", #"EC": #"593", #"EG":#"20", #"ER": #"291", #"EE":#"372",#"ES": #"34", #"ET": #"251", #"FM": #"691", #"FK": #"500", #"FO": #"298", #"FJ": #"679", #"FI":#"358", #"FR": #"33", #"GB":#"44", #"GF": #"594", #"GA":#"241", #"GS": #"500", #"GM":#"220", #"GE":#"995",#"GH":#"233", #"GI": #"350", #"GQ": #"240", #"GR": #"30", #"GG": #"44", #"GL": #"299", #"GD":#"1", #"GP": #"590", #"GU": #"1", #"GT": #"502", #"GN":#"224",#"GW": #"245", #"GY": #"595", #"HT": #"509", #"HR": #"385", #"HN":#"504", #"HU": #"36", #"HK": #"852", #"IR": #"98", #"IM": #"44", #"IL": #"972", #"IO":#"246", #"IS": #"354", #"IN": #"91", #"ID":#"62", #"IQ":#"964", #"IE": #"353",#"IT":#"39", #"JM":#"1", #"JP": #"81", #"JO": #"962", #"JE":#"44", #"KP": #"850", #"KR": #"82",#"KZ":#"77", #"KE": #"254", #"KI": #"686", #"KW": #"965", #"KG":#"996",#"KN":#"1", #"LC": #"1", #"LV": #"371", #"LB": #"961", #"LK":#"94", #"LS": #"266", #"LR":#"231", #"LI": #"423", #"LT": #"370", #"LU": #"352", #"LA": #"856", #"LY":#"218", #"MO": #"853", #"MK": #"389", #"MG":#"261", #"MW": #"265", #"MY": #"60",#"MV": #"960", #"ML":#"223", #"MT": #"356", #"MH": #"692", #"MQ": #"596", #"MR":#"222", #"MU": #"230", #"MX": #"52",#"MC": #"377", #"MN": #"976", #"ME": #"382", #"MP": #"1", #"MS": #"1", #"MA":#"212", #"MM": #"95", #"MF": #"590", #"MD":#"373", #"MZ": #"258", #"NA":#"264", #"NR":#"674", #"NP":#"977", #"NL": #"31",#"NC": #"687", #"NZ":#"64", #"NI": #"505", #"NE": #"227", #"NG": #"234", #"NU":#"683", #"NF": #"672", #"NO": #"47",#"OM": #"968", #"PK": #"92", #"PM": #"508", #"PW": #"680", #"PF": #"689", #"PA": #"507", #"PG":#"675", #"PY": #"595", #"PE": #"51", #"PH": #"63", #"PL":#"48", #"PN": #"872",#"PT": #"351", #"PR": #"1",#"PS": #"970", #"QA": #"974", #"RO":#"40", #"RE":#"262", #"RS": #"381", #"RU": #"7", #"RW": #"250", #"SM": #"378", #"SA":#"966", #"SN": #"221", #"SC": #"248", #"SL":#"232",#"SG": #"65", #"SK": #"421", #"SI": #"386", #"SB":#"677", #"SH": #"290", #"SD": #"249", #"SR": #"597",#"SZ": #"268", #"SE":#"46", #"SV": #"503", #"ST": #"239",#"SO": #"252", #"SJ": #"47", #"SY":#"963", #"TW": #"886", #"TZ": #"255", #"TL": #"670", #"TD": #"235", #"TJ": #"992", #"TH": #"66", #"TG":#"228", #"TK": #"690", #"TO": #"676", #"TT": #"1", #"TN":#"216",#"TR": #"90", #"TM": #"993", #"TC": #"1", #"TV":#"688", #"UG": #"256", #"UA": #"380", #"US": #"1", #"UY": #"598",#"UZ": #"998", #"VA":#"379", #"VE":#"58", #"VN": #"84", #"VG": #"1", #"VI": #"1",#"VC":#"1", #"VU":#"678", #"WS": #"685", #"WF": #"681", #"YE": #"967", #"YT": #"262",#"ZA": #"27" , #"ZM": #"260", #"ZW":#"263"};
return [NSString stringWithFormat:#"+%#", [code objectForKey:[countryISOCode uppercaseString]]];
}
Swift 5 Support and using optionals here is my solution:
static func GetCountryCallingCode(countryRegionCode:String) -> String? {
let prefixCodes = ["AF": "93", "AE": "971", "AL": "355", "AN": "599", "AS":"1", "AD": "376", "AO": "244", "AI": "1", "AG":"1", "AR": "54","AM": "374", "AW": "297", "AU":"61", "AT": "43","AZ": "994", "BS": "1", "BH":"973", "BF": "226","BI": "257", "BD": "880", "BB": "1", "BY": "375", "BE":"32","BZ": "501", "BJ": "229", "BM": "1", "BT":"975", "BA": "387", "BW": "267", "BR": "55", "BG": "359", "BO": "591", "BL": "590", "BN": "673", "CC": "61", "CD":"243","CI": "225", "KH":"855", "CM": "237", "CA": "1", "CV": "238", "KY":"345", "CF":"236", "CH": "41", "CL": "56", "CN":"86","CX": "61", "CO": "57", "KM": "269", "CG":"242", "CK": "682", "CR": "506", "CU":"53", "CY":"537","CZ": "420", "DE": "49", "DK": "45", "DJ":"253", "DM": "1", "DO": "1", "DZ": "213", "EC": "593", "EG":"20", "ER": "291", "EE":"372","ES": "34", "ET": "251", "FM": "691", "FK": "500", "FO": "298", "FJ": "679", "FI":"358", "FR": "33", "GB":"44", "GF": "594", "GA":"241", "GS": "500", "GM":"220", "GE":"995","GH":"233", "GI": "350", "GQ": "240", "GR": "30", "GG": "44", "GL": "299", "GD":"1", "GP": "590", "GU": "1", "GT": "502", "GN":"224","GW": "245", "GY": "595", "HT": "509", "HR": "385", "HN":"504", "HU": "36", "HK": "852", "IR": "98", "IM": "44", "IL": "972", "IO":"246", "IS": "354", "IN": "91", "ID":"62", "IQ":"964", "IE": "353","IT":"39", "JM":"1", "JP": "81", "JO": "962", "JE":"44", "KP": "850", "KR": "82","KZ":"77", "KE": "254", "KI": "686", "KW": "965", "KG":"996","KN":"1", "LC": "1", "LV": "371", "LB": "961", "LK":"94", "LS": "266", "LR":"231", "LI": "423", "LT": "370", "LU": "352", "LA": "856", "LY":"218", "MO": "853", "MK": "389", "MG":"261", "MW": "265", "MY": "60","MV": "960", "ML":"223", "MT": "356", "MH": "692", "MQ": "596", "MR":"222", "MU": "230", "MX": "52","MC": "377", "MN": "976", "ME": "382", "MP": "1", "MS": "1", "MA":"212", "MM": "95", "MF": "590", "MD":"373", "MZ": "258", "NA":"264", "NR":"674", "NP":"977", "NL": "31","NC": "687", "NZ":"64", "NI": "505", "NE": "227", "NG": "234", "NU":"683", "NF": "672", "NO": "47","OM": "968", "PK": "92", "PM": "508", "PW": "680", "PF": "689", "PA": "507", "PG":"675", "PY": "595", "PE": "51", "PH": "63", "PL":"48", "PN": "872","PT": "351", "PR": "1","PS": "970", "QA": "974", "RO":"40", "RE":"262", "RS": "381", "RU": "7", "RW": "250", "SM": "378", "SA":"966", "SN": "221", "SC": "248", "SL":"232","SG": "65", "SK": "421", "SI": "386", "SB":"677", "SH": "290", "SD": "249", "SR": "597","SZ": "268", "SE":"46", "SV": "503", "ST": "239","SO": "252", "SJ": "47", "SY":"963", "TW": "886", "TZ": "255", "TL": "670", "TD": "235", "TJ": "992", "TH": "66", "TG":"228", "TK": "690", "TO": "676", "TT": "1", "TN":"216","TR": "90", "TM": "993", "TC": "1", "TV":"688", "UG": "256", "UA": "380", "US": "1", "UY": "598","UZ": "998", "VA":"379", "VE":"58", "VN": "84", "VG": "1", "VI": "1","VC":"1", "VU":"678", "WS": "685", "WF": "681", "YE": "967", "YT": "262","ZA": "27" , "ZM": "260", "ZW":"263"]
let countryDialingCode = prefixCodes[countryRegionCode]
return countryDialingCode
}
guard let regionCode = NSLocale.current.regionCode,
let callingCode = GetCountryCallingCode(countryRegionCode: regionCode )
else { return }
print("Region: \(regionCode) Country calling code is \(callingCode)")
import CoreTelephony
/// Method to get the iso calling code
///
/// - Returns: String
public static func getCallingCodePrefix() -> String {
let networkInfo = CTTelephonyNetworkInfo()
let phoneNumberKit = PhoneNumberKit()
if #available(iOS 12.0, *) {
if let carrier = networkInfo.serviceSubscriberCellularProviders?.map({ $0.1 }).first(where: { $0.isoCountryCode != nil }), let isoCode = carrier.isoCountryCode?.uppercased(), let prefixCode = phoneNumberKit.countryCode(for: isoCode) {
return "+" + String(prefixCode)
}
} else {
// Fallback on earlier versions
if let carrier = networkInfo.subscriberCellularProvider, let isoCode = carrier.isoCountryCode?.uppercased(), let prefixCode = phoneNumberKit.countryCode(for: isoCode) {
return "+" + String(prefixCode)
}
}
return "+"
}
Use this code to get the user's country in iOS:
func countryName(from countryCode: String) -> String {
if let name = (Locale.current as NSLocale).displayName(forKey: .countryCode, value: countryCode) {
return name
} else {
return countryCode
}
}
//Locale.current.regionCode this is used for Get user current country region code
countryName(from: Locale.current.regionCode ?? "")
Ruby 2.2.3, Rails 4.2.1
I have a large number of arrays of strings that I define as constants for use throughout an application. They are various sets of ISO country codes, language codes, that sort of thing, so two to four characters, numbered in the hundreds of unique values each.
The different arrays are collections of these, so NORTH_AMERICA_COUNTRY_CODES might be an array of a dozen of so country codes, AFRICA_COUNTRY_CODES might be an array of around 60. Many of them overlap (various versions of the Commonwealth countries, for example).
The arrays are used in comparison with other arbitrary arrays of country codes for logic such as "Subtract this list of countries from Africa".
So I'm wondering whether, when I generate these constants, I ought to freeze the strings within the arrays, so instead of:
WORLD_COUNTRIES = Countries.pluck(:country_code).freeze
... maybe ...
WORLD_COUNTRIES = Countries.pluck(:country_code).map{|c| c.freeze}.freeze
Is there a way of quantifying the potential benefits?
I considered using arrays of symbols instead of arrays of strings, but the arbitrary arrays that these are used with are stored in PostgreSQL text arrays, and it seems like I'd need to serialise those columns instead, or maybe override the getter and setter methods to change the values between arrays of strings and arrays of symbols. Ugh.
Edit
Testing results, in which I've attempted to benchmark three situations:
Comparing a frozen array of unfrozen strings with an unfrozen array of unfrozen strings
Comparing a frozen array of frozen strings with an unfrozen array of unfrozen strings
Comparing a frozen array of symbols with an unfrozen array of symbols (in case I bit the bullet and went all symbolic on this).
Any thoughts on methodology or interpretation gratefully received. I'm not sure whether the similarity in results between the first two indicates that they are in all respects the same, but I'd be keen on anything that can directly point to differences in memory allocation.
Script:
require 'benchmark'
country_list = ["AD", "AE", "AF", "AG", "AI", "AL", "AM", "AN", "AO", "AQ", "AR", "AS", "AT", "AU", "AW", "AX", "AZ", "BA", "BB", "BD", "BE", "BF", "BG", "BH", "BI", "BJ", "BL", "BM", "BN", "BO", "BQ", "BR", "BS", "BT", "BV", "BW", "BY", "BZ", "CA", "CC", "CD", "CF", "CG", "CH", "CI", "CK", "CL", "CM", "CN", "CO", "CR", "CS", "CU", "CV", "CW", "CX", "CY", "CZ", "DE", "DJ", "DK", "DM", "DO", "DZ", "EC", "EE", "EG", "EH", "ER", "ES", "ET", "FI", "FJ", "FK", "FM", "FO", "FR", "GA", "GB", "GD", "GE", "GF", "GG", "GH", "GI", "GL", "GM", "GN", "GP", "GQ", "GR", "GS", "GT", "GU", "GW", "GY", "HK", "HM", "HN", "HR", "HT", "HU", "ID", "IE", "IL", "IM", "IN", "IO", "IQ", "IR", "IS", "IT", "JE", "JM", "JO", "JP", "KE", "KG", "KH", "KI", "KM", "KN", "KP", "KR", "KW", "KY", "KZ", "LA", "LB", "LC", "LI", "LK", "LR", "LS", "LT", "LU", "LV", "LY", "MA", "MC", "MD", "ME", "MF", "MG", "MH", "MK", "ML", "MM", "MN", "MO", "MP", "MQ", "MR", "MS", "MT", "MU", "MV", "MW", "MX", "MY", "MZ", "NA", "NC", "NE", "NF", "NG", "NI", "NL", "NO", "NP", "NR", "NU", "NZ", "OM", "PA", "PE", "PF", "PG", "PH", "PK", "PL", "PM", "PN", "PR", "PS", "PT", "PW", "PY", "QA", "RE", "RO", "RS", "RU", "RW", "SA", "SB", "SC", "SD", "SE", "SG", "SH", "SI", "SJ", "SK", "SL", "SM", "SN", "SO", "SR", "SS", "ST", "SV", "SX", "SY", "SZ", "TC", "TD", "TF", "TG", "TH", "TJ", "TK", "TL", "TM", "TN", "TO", "TR", "TT", "TV", "TW", "TZ", "UA", "UG", "UM", "US", "UY", "UZ", "VA", "VC", "VE", "VG", "VI", "VN", "VU", "WF", "WS", "YE", "YT", "YU", "ZA", "ZM", "ZW"]
FROZEN_ARRAY = country_list.dup.freeze
puts FROZEN_ARRAY.size
FROZEN_ARRAY_AND_STRINGS = country_list.dup.map{|x| x.freeze}.freeze
FROZEN_ARRAY_AND_SYMBOLS = country_list.dup.map{|x| x.to_sym}.freeze
comp_s = %w(AD AT BE CY EE FI FR DE ES GR IE IT LU LV MC ME MT NL PT SI SK SM VA)
comp_sym = %w(AD AT BE CY EE FI FR DE ES GR IE IT LU LV MC ME MT NL PT SI SK SM VA).map{|x| x.to_sym}
Benchmark.bm do |x|
x.report("frozen string" ) { 10000.times {|i| c = (FROZEN_ARRAY_AND_STRINGS & comp_s.dup) }}
x.report("unfrozen string") { 10000.times {|i| c = (FROZEN_ARRAY & comp_s.dup) }}
x.report("symbols" ) { 10000.times {|i| c = (FROZEN_ARRAY_AND_SYMBOLS & comp_sym.dup) }}
end
Benchmark.bmbm do |x|
x.report("frozen string" ) { 10000.times {|i| c = (FROZEN_ARRAY_AND_STRINGS & comp_s.dup) }}
x.report("unfrozen string") { 10000.times {|i| c = (FROZEN_ARRAY & comp_s.dup) }}
x.report("symbols" ) { 10000.times {|i| c = (FROZEN_ARRAY_AND_SYMBOLS & comp_sym.dup) }}
end
Result:
2.2.3 :001 > require 'benchmark'
=> false
2.2.3 :002 >
2.2.3 :003 > country_list = ["AD", "AE", "AF", "AG", "AI", "AL", "AM", "AN", "AO", "AQ", "AR", "AS", "AT", "AU", "AW", "AX", "AZ", "BA", "BB", "BD", "BE", "BF", "BG", "BH", "BI", "BJ", "BL", "BM", "BN", "BO", "BQ", "BR", "BS", "BT", "BV", "BW", "BY", "BZ", "CA", "CC", "CD", "CF", "CG", "CH", "CI", "CK", "CL", "CM", "CN", "CO", "CR", "CS", "CU", "CV", "CW", "CX", "CY", "CZ", "DE", "DJ", "DK", "DM", "DO", "DZ", "EC", "EE", "EG", "EH", "ER", "ES", "ET", "FI", "FJ", "FK", "FM", "FO", "FR", "GA", "GB", "GD", "GE", "GF", "GG", "GH", "GI", "GL", "GM", "GN", "GP", "GQ", "GR", "GS", "GT", "GU", "GW", "GY", "HK", "HM", "HN", "HR", "HT", "HU", "ID", "IE", "IL", "IM", "IN", "IO", "IQ", "IR", "IS", "IT", "JE", "JM", "JO", "JP", "KE", "KG", "KH", "KI", "KM", "KN", "KP", "KR", "KW", "KY", "KZ", "LA", "LB", "LC", "LI", "LK", "LR", "LS", "LT", "LU", "LV", "LY", "MA", "MC", "MD", "ME", "MF", "MG", "MH", "MK", "ML", "MM", "MN", "MO", "MP", "MQ", "MR", "MS", "MT", "MU", "MV", "MW", "MX", "MY", "MZ", "NA", "NC", "NE", "NF", "NG", "NI", "NL", "NO", "NP", "NR", "NU", "NZ", "OM", "PA", "PE", "PF", "PG", "PH", "PK", "PL", "PM", "PN", "PR", "PS", "PT", "PW", "PY", "QA", "RE", "RO", "RS", "RU", "RW", "SA", "SB", "SC", "SD", "SE", "SG", "SH", "SI", "SJ", "SK", "SL", "SM", "SN", "SO", "SR", "SS", "ST", "SV", "SX", "SY", "SZ", "TC", "TD", "TF", "TG", "TH", "TJ", "TK", "TL", "TM", "TN", "TO", "TR", "TT", "TV", "TW", "TZ", "UA", "UG", "UM", "US", "UY", "UZ", "VA", "VC", "VE", "VG", "VI", "VN", "VU", "WF", "WS", "YE", "YT", "YU", "ZA", "ZM", "ZW"]
=> ["AD", "AE", "AF", "AG", "AI", "AL", "AM", "AN", "AO", "AQ", "AR", "AS", "AT", "AU", "AW", "AX", "AZ", "BA", "BB", "BD", "BE", "BF", "BG", "BH", "BI", "BJ", "BL", "BM", "BN", "BO", "BQ", "BR", "BS", "BT", "BV", "BW", "BY", "BZ", "CA", "CC", "CD", "CF", "CG", "CH", "CI", "CK", "CL", "CM", "CN", "CO", "CR", "CS", "CU", "CV", "CW", "CX", "CY", "CZ", "DE", "DJ", "DK", "DM", "DO", "DZ", "EC", "EE", "EG", "EH", "ER", "ES", "ET", "FI", "FJ", "FK", "FM", "FO", "FR", "GA", "GB", "GD", "GE", "GF", "GG", "GH", "GI", "GL", "GM", "GN", "GP", "GQ", "GR", "GS", "GT", "GU", "GW", "GY", "HK", "HM", "HN", "HR", "HT", "HU", "ID", "IE", "IL", "IM", "IN", "IO", "IQ", "IR", "IS", "IT", "JE", "JM", "JO", "JP", "KE", "KG", "KH", "KI", "KM", "KN", "KP", "KR", "KW", "KY", "KZ", "LA", "LB", "LC", "LI", "LK", "LR", "LS", "LT", "LU", "LV", "LY", "MA", "MC", "MD", "ME", "MF", "MG", "MH", "MK", "ML", "MM", "MN", "MO", "MP", "MQ", "MR", "MS", "MT", "MU", "MV", "MW", "MX", "MY", "MZ", "NA", "NC", "NE", "NF", "NG", "NI", "NL", "NO", "NP", "NR", "NU", "NZ", "OM", "PA", "PE", "PF", "PG", "PH", "PK", "PL", "PM", "PN", "PR", "PS", "PT", "PW", "PY", "QA", "RE", "RO", "RS", "RU", "RW", "SA", "SB", "SC", "SD", "SE", "SG", "SH", "SI", "SJ", "SK", "SL", "SM", "SN", "SO", "SR", "SS", "ST", "SV", "SX", "SY", "SZ", "TC", "TD", "TF", "TG", "TH", "TJ", "TK", "TL", "TM", "TN", "TO", "TR", "TT", "TV", "TW", "TZ", "UA", "UG", "UM", "US", "UY", "UZ", "VA", "VC", "VE", "VG", "VI", "VN", "VU", "WF", "WS", "YE", "YT", "YU", "ZA", "ZM", "ZW"]
2.2.3 :004 > FROZEN_ARRAY = country_list.dup.freeze
=> ["AD", "AE", "AF", "AG", "AI", "AL", "AM", "AN", "AO", "AQ", "AR", "AS", "AT", "AU", "AW", "AX", "AZ", "BA", "BB", "BD", "BE", "BF", "BG", "BH", "BI", "BJ", "BL", "BM", "BN", "BO", "BQ", "BR", "BS", "BT", "BV", "BW", "BY", "BZ", "CA", "CC", "CD", "CF", "CG", "CH", "CI", "CK", "CL", "CM", "CN", "CO", "CR", "CS", "CU", "CV", "CW", "CX", "CY", "CZ", "DE", "DJ", "DK", "DM", "DO", "DZ", "EC", "EE", "EG", "EH", "ER", "ES", "ET", "FI", "FJ", "FK", "FM", "FO", "FR", "GA", "GB", "GD", "GE", "GF", "GG", "GH", "GI", "GL", "GM", "GN", "GP", "GQ", "GR", "GS", "GT", "GU", "GW", "GY", "HK", "HM", "HN", "HR", "HT", "HU", "ID", "IE", "IL", "IM", "IN", "IO", "IQ", "IR", "IS", "IT", "JE", "JM", "JO", "JP", "KE", "KG", "KH", "KI", "KM", "KN", "KP", "KR", "KW", "KY", "KZ", "LA", "LB", "LC", "LI", "LK", "LR", "LS", "LT", "LU", "LV", "LY", "MA", "MC", "MD", "ME", "MF", "MG", "MH", "MK", "ML", "MM", "MN", "MO", "MP", "MQ", "MR", "MS", "MT", "MU", "MV", "MW", "MX", "MY", "MZ", "NA", "NC", "NE", "NF", "NG", "NI", "NL", "NO", "NP", "NR", "NU", "NZ", "OM", "PA", "PE", "PF", "PG", "PH", "PK", "PL", "PM", "PN", "PR", "PS", "PT", "PW", "PY", "QA", "RE", "RO", "RS", "RU", "RW", "SA", "SB", "SC", "SD", "SE", "SG", "SH", "SI", "SJ", "SK", "SL", "SM", "SN", "SO", "SR", "SS", "ST", "SV", "SX", "SY", "SZ", "TC", "TD", "TF", "TG", "TH", "TJ", "TK", "TL", "TM", "TN", "TO", "TR", "TT", "TV", "TW", "TZ", "UA", "UG", "UM", "US", "UY", "UZ", "VA", "VC", "VE", "VG", "VI", "VN", "VU", "WF", "WS", "YE", "YT", "YU", "ZA", "ZM", "ZW"]
2.2.3 :005 > puts FROZEN_ARRAY.size
252
=> nil
2.2.3 :006 > FROZEN_ARRAY_AND_STRINGS = country_list.dup.map{|x| x.freeze}.freeze
=> ["AD", "AE", "AF", "AG", "AI", "AL", "AM", "AN", "AO", "AQ", "AR", "AS", "AT", "AU", "AW", "AX", "AZ", "BA", "BB", "BD", "BE", "BF", "BG", "BH", "BI", "BJ", "BL", "BM", "BN", "BO", "BQ", "BR", "BS", "BT", "BV", "BW", "BY", "BZ", "CA", "CC", "CD", "CF", "CG", "CH", "CI", "CK", "CL", "CM", "CN", "CO", "CR", "CS", "CU", "CV", "CW", "CX", "CY", "CZ", "DE", "DJ", "DK", "DM", "DO", "DZ", "EC", "EE", "EG", "EH", "ER", "ES", "ET", "FI", "FJ", "FK", "FM", "FO", "FR", "GA", "GB", "GD", "GE", "GF", "GG", "GH", "GI", "GL", "GM", "GN", "GP", "GQ", "GR", "GS", "GT", "GU", "GW", "GY", "HK", "HM", "HN", "HR", "HT", "HU", "ID", "IE", "IL", "IM", "IN", "IO", "IQ", "IR", "IS", "IT", "JE", "JM", "JO", "JP", "KE", "KG", "KH", "KI", "KM", "KN", "KP", "KR", "KW", "KY", "KZ", "LA", "LB", "LC", "LI", "LK", "LR", "LS", "LT", "LU", "LV", "LY", "MA", "MC", "MD", "ME", "MF", "MG", "MH", "MK", "ML", "MM", "MN", "MO", "MP", "MQ", "MR", "MS", "MT", "MU", "MV", "MW", "MX", "MY", "MZ", "NA", "NC", "NE", "NF", "NG", "NI", "NL", "NO", "NP", "NR", "NU", "NZ", "OM", "PA", "PE", "PF", "PG", "PH", "PK", "PL", "PM", "PN", "PR", "PS", "PT", "PW", "PY", "QA", "RE", "RO", "RS", "RU", "RW", "SA", "SB", "SC", "SD", "SE", "SG", "SH", "SI", "SJ", "SK", "SL", "SM", "SN", "SO", "SR", "SS", "ST", "SV", "SX", "SY", "SZ", "TC", "TD", "TF", "TG", "TH", "TJ", "TK", "TL", "TM", "TN", "TO", "TR", "TT", "TV", "TW", "TZ", "UA", "UG", "UM", "US", "UY", "UZ", "VA", "VC", "VE", "VG", "VI", "VN", "VU", "WF", "WS", "YE", "YT", "YU", "ZA", "ZM", "ZW"]
2.2.3 :007 > FROZEN_ARRAY_AND_SYMBOLS = country_list.dup.map{|x| x.to_sym}.freeze
=> [:AD, :AE, :AF, :AG, :AI, :AL, :AM, :AN, :AO, :AQ, :AR, :AS, :AT, :AU, :AW, :AX, :AZ, :BA, :BB, :BD, :BE, :BF, :BG, :BH, :BI, :BJ, :BL, :BM, :BN, :BO, :BQ, :BR, :BS, :BT, :BV, :BW, :BY, :BZ, :CA, :CC, :CD, :CF, :CG, :CH, :CI, :CK, :CL, :CM, :CN, :CO, :CR, :CS, :CU, :CV, :CW, :CX, :CY, :CZ, :DE, :DJ, :DK, :DM, :DO, :DZ, :EC, :EE, :EG, :EH, :ER, :ES, :ET, :FI, :FJ, :FK, :FM, :FO, :FR, :GA, :GB, :GD, :GE, :GF, :GG, :GH, :GI, :GL, :GM, :GN, :GP, :GQ, :GR, :GS, :GT, :GU, :GW, :GY, :HK, :HM, :HN, :HR, :HT, :HU, :ID, :IE, :IL, :IM, :IN, :IO, :IQ, :IR, :IS, :IT, :JE, :JM, :JO, :JP, :KE, :KG, :KH, :KI, :KM, :KN, :KP, :KR, :KW, :KY, :KZ, :LA, :LB, :LC, :LI, :LK, :LR, :LS, :LT, :LU, :LV, :LY, :MA, :MC, :MD, :ME, :MF, :MG, :MH, :MK, :ML, :MM, :MN, :MO, :MP, :MQ, :MR, :MS, :MT, :MU, :MV, :MW, :MX, :MY, :MZ, :NA, :NC, :NE, :NF, :NG, :NI, :NL, :NO, :NP, :NR, :NU, :NZ, :OM, :PA, :PE, :PF, :PG, :PH, :PK, :PL, :PM, :PN, :PR, :PS, :PT, :PW, :PY, :QA, :RE, :RO, :RS, :RU, :RW, :SA, :SB, :SC, :SD, :SE, :SG, :SH, :SI, :SJ, :SK, :SL, :SM, :SN, :SO, :SR, :SS, :ST, :SV, :SX, :SY, :SZ, :TC, :TD, :TF, :TG, :TH, :TJ, :TK, :TL, :TM, :TN, :TO, :TR, :TT, :TV, :TW, :TZ, :UA, :UG, :UM, :US, :UY, :UZ, :VA, :VC, :VE, :VG, :VI, :VN, :VU, :WF, :WS, :YE, :YT, :YU, :ZA, :ZM, :ZW]
2.2.3 :008 > comp_s = %w(AD AT BE CY EE FI FR DE ES GR IE IT LU LV MC ME MT NL PT SI SK SM VA)
=> ["AD", "AT", "BE", "CY", "EE", "FI", "FR", "DE", "ES", "GR", "IE", "IT", "LU", "LV", "MC", "ME", "MT", "NL", "PT", "SI", "SK", "SM", "VA"]
2.2.3 :009 > comp_sym = %w(AD AT BE CY EE FI FR DE ES GR IE IT LU LV MC ME MT NL PT SI SK SM VA).map{|x| x.to_sym}
=> [:AD, :AT, :BE, :CY, :EE, :FI, :FR, :DE, :ES, :GR, :IE, :IT, :LU, :LV, :MC, :ME, :MT, :NL, :PT, :SI, :SK, :SM, :VA]
2.2.3 :010 >
2.2.3 :011 >
2.2.3 :012 > Benchmark.bm do |x|
2.2.3 :013 > x.report("frozen string" ) { 10000.times {|i| c = (FROZEN_ARRAY_AND_STRINGS & comp_s.dup) }}
2.2.3 :014?> x.report("unfrozen string") { 10000.times {|i| c = (FROZEN_ARRAY & comp_s.dup) }}
2.2.3 :015?> x.report("symbols" ) { 10000.times {|i| c = (FROZEN_ARRAY_AND_SYMBOLS & comp_sym.dup) }}
2.2.3 :016?> end
user system total real
frozen string 0.190000 0.000000 0.190000 ( 0.194141)
unfrozen string 0.170000 0.010000 0.180000 ( 0.174675)
symbols 0.080000 0.000000 0.080000 ( 0.081507)
=> [#<Benchmark::Tms:0x007f810c3aca70 #label="frozen string", #real=0.1941408810671419, #cstime=0.0, #cutime=0.0, #stime=0.0, #utime=0.1899999999999995, #total=0.1899999999999995>, #<Benchmark::Tms:0x007f810c82b538 #label="unfrozen string", #real=0.1746752569451928, #cstime=0.0, #cutime=0.0, #stime=0.010000000000000009, #utime=0.16999999999999993, #total=0.17999999999999994>, #<Benchmark::Tms:0x007f810af2cfa0 #label="symbols", #real=0.08150708093307912, #cstime=0.0, #cutime=0.0, #stime=0.0, #utime=0.08000000000000007, #total=0.08000000000000007>]
2.2.3 :017 >
2.2.3 :018 >
2.2.3 :019 > Benchmark.bmbm do |x|
2.2.3 :020 > x.report("frozen string" ) { 10000.times {|i| c = (FROZEN_ARRAY_AND_STRINGS & comp_s.dup) }}
2.2.3 :021?> x.report("unfrozen string") { 10000.times {|i| c = (FROZEN_ARRAY & comp_s.dup) }}
2.2.3 :022?> x.report("symbols" ) { 10000.times {|i| c = (FROZEN_ARRAY_AND_SYMBOLS & comp_sym.dup) }}
2.2.3 :023?> end
Rehearsal ---------------------------------------------------
frozen string 0.180000 0.000000 0.180000 ( 0.183846)
unfrozen string 0.200000 0.000000 0.200000 ( 0.196311)
symbols 0.080000 0.000000 0.080000 ( 0.082794)
------------------------------------------ total: 0.460000sec
user system total real
frozen string 0.160000 0.000000 0.160000 ( 0.167051)
unfrozen string 0.170000 0.000000 0.170000 ( 0.171601)
symbols 0.080000 0.000000 0.080000 ( 0.078746)
=> [#<Benchmark::Tms:0x007f811022a388 #label="frozen string", #real=0.1670510449912399, #cstime=0.0, #cutime=0.0, #stime=0.0, #utime=0.16000000000000014, #total=0.16000000000000014>, #<Benchmark::Tms:0x007f811022a4c8 #label="unfrozen string", #real=0.17160122003406286, #cstime=0.0, #cutime=0.0, #stime=0.0, #utime=0.16999999999999993, #total=0.16999999999999993>, #<Benchmark::Tms:0x007f8108eb1c58 #label="symbols", #real=0.07874645793344826, #cstime=0.0, #cutime=0.0, #stime=0.0, #utime=0.08000000000000007, #total=0.08000000000000007>]
2.2.3 :024 >
2.2.3 :025 >
2.2.3 :026 >
Since you're dealing with a small number of values, and since the performance benefits of symbols are evident from your testing, just go with symbols.
BTW, you can use map(&:to_sym) instead of map {|x| x.to_sym}.