Cache Formatters for Efficiency
Creating a date formatter is not a cheap operation. If you are likely to use a formatter frequently, it is typically more efficient to cache a single instance than to create and dispose of multiple instances. One approach is to use a static variable.
If you cache date formatters (or any other objects that depend on the user’s current locale), you should subscribe to the NSCurrentLocaleDidChangeNotification notification and update your cached objects when the current locale changes. The code in Listing 3 defines sUserVisibleDateFormatter outside of the method so that other code, not shown, can update it as necessary. In contrast, sRFC3339DateFormatter is defined inside the method because, by design, it is not dependent on the user’s locale settings.
Reference: Date Formatters
Codes
Wednesday, 3 July 2013
Monday, 1 July 2013
NSDateFormatter formatting
a: AM/PM
A: 0~86399999 (Millisecond of Day)
c/cc: 1~7 (Day of Week)
ccc: Sun/Mon/Tue/Wed/Thu/Fri/Sat
cccc: Sunday/Monday/Tuesday/Wednesday/Thursday/Friday/Saturday
d: 1~31 (0 padded Day of Month)
D: 1~366 (0 padded Day of Year)
e: 1~7 (0 padded Day of Week)
E~EEE: Sun/Mon/Tue/Wed/Thu/Fri/Sat
EEEE: Sunday/Monday/Tuesday/Wednesday/Thursday/Friday/Saturday
F: 1~5 (0 padded Week of Month, first day of week = Monday)
g: Julian Day Number (number of days since 4713 BC January 1)
G~GGG: BC/AD (Era Designator Abbreviated)
GGGG: Before Christ/Anno Domini
h: 1~12 (0 padded Hour (12hr))
H: 0~23 (0 padded Hour (24hr))
k: 1~24 (0 padded Hour (24hr)
K: 0~11 (0 padded Hour (12hr))
L/LL: 1~12 (0 padded Month)
LLL: Jan/Feb/Mar/Apr/May/Jun/Jul/Aug/Sep/Oct/Nov/Dec
LLLL: January/February/March/April/May/June/July/August/September/October/November/December
m: 0~59 (0 padded Minute)
M/MM: 1~12 (0 padded Month)
MMM: Jan/Feb/Mar/Apr/May/Jun/Jul/Aug/Sep/Oct/Nov/Dec
MMMM: January/February/March/April/May/June/July/August/September/October/November/December
q/qq: 1~4 (0 padded Quarter)
qqq: Q1/Q2/Q3/Q4
qqqq: 1st quarter/2nd quarter/3rd quarter/4th quarter
Q/QQ: 1~4 (0 padded Quarter)
QQQ: Q1/Q2/Q3/Q4
QQQQ: 1st quarter/2nd quarter/3rd quarter/4th quarter
s: 0~59 (0 padded Second)
S: (rounded Sub-Second)
u: (0 padded Year)
v~vvv: (General GMT Timezone Abbreviation)
vvvv: (General GMT Timezone Name)
w: 1~53 (0 padded Week of Year, 1st day of week = Sunday, NB: 1st week of year starts from the last Sunday of last year)
W: 1~5 (0 padded Week of Month, 1st day of week = Sunday)
y/yyyy: (Full Year)
yy/yyy: (2 Digits Year)
Y/YYYY: (Full Year, starting from the Sunday of the 1st week of year)
YY/YYY: (2 Digits Year, starting from the Sunday of the 1st week of year)
z~zzz: (Specific GMT Timezone Abbreviation)
zzzz: (Specific GMT Timezone Name)
Z: +0000 (RFC 822 Timezone)
References:
1. NSDateFormatter formatting
2. Date Formatters
3. Date Format Patterns
A: 0~86399999 (Millisecond of Day)
c/cc: 1~7 (Day of Week)
ccc: Sun/Mon/Tue/Wed/Thu/Fri/Sat
cccc: Sunday/Monday/Tuesday/Wednesday/Thursday/Friday/Saturday
d: 1~31 (0 padded Day of Month)
D: 1~366 (0 padded Day of Year)
e: 1~7 (0 padded Day of Week)
E~EEE: Sun/Mon/Tue/Wed/Thu/Fri/Sat
EEEE: Sunday/Monday/Tuesday/Wednesday/Thursday/Friday/Saturday
F: 1~5 (0 padded Week of Month, first day of week = Monday)
g: Julian Day Number (number of days since 4713 BC January 1)
G~GGG: BC/AD (Era Designator Abbreviated)
GGGG: Before Christ/Anno Domini
h: 1~12 (0 padded Hour (12hr))
H: 0~23 (0 padded Hour (24hr))
k: 1~24 (0 padded Hour (24hr)
K: 0~11 (0 padded Hour (12hr))
L/LL: 1~12 (0 padded Month)
LLL: Jan/Feb/Mar/Apr/May/Jun/Jul/Aug/Sep/Oct/Nov/Dec
LLLL: January/February/March/April/May/June/July/August/September/October/November/December
m: 0~59 (0 padded Minute)
M/MM: 1~12 (0 padded Month)
MMM: Jan/Feb/Mar/Apr/May/Jun/Jul/Aug/Sep/Oct/Nov/Dec
MMMM: January/February/March/April/May/June/July/August/September/October/November/December
q/qq: 1~4 (0 padded Quarter)
qqq: Q1/Q2/Q3/Q4
qqqq: 1st quarter/2nd quarter/3rd quarter/4th quarter
Q/QQ: 1~4 (0 padded Quarter)
QQQ: Q1/Q2/Q3/Q4
QQQQ: 1st quarter/2nd quarter/3rd quarter/4th quarter
s: 0~59 (0 padded Second)
S: (rounded Sub-Second)
u: (0 padded Year)
v~vvv: (General GMT Timezone Abbreviation)
vvvv: (General GMT Timezone Name)
w: 1~53 (0 padded Week of Year, 1st day of week = Sunday, NB: 1st week of year starts from the last Sunday of last year)
W: 1~5 (0 padded Week of Month, 1st day of week = Sunday)
y/yyyy: (Full Year)
yy/yyy: (2 Digits Year)
Y/YYYY: (Full Year, starting from the Sunday of the 1st week of year)
YY/YYY: (2 Digits Year, starting from the Sunday of the 1st week of year)
z~zzz: (Specific GMT Timezone Abbreviation)
zzzz: (Specific GMT Timezone Name)
Z: +0000 (RFC 822 Timezone)
References:
1. NSDateFormatter formatting
2. Date Formatters
3. Date Format Patterns
Tuesday, 25 June 2013
JSP MVC (model-view-controller) example
This is a simple Model View Controller (MVC) example:
- Controller: Servlet controller. Let the controller servlet listen on a specific url-pattern of interest in web.xml, and forward the request to the JSP page of interest using RequestDispatcher.
- Model: A simple java class
- View: An JSP view
(1) Servlet Controller:
public class ExampleServlet extends HttpServlet {
public void doPost( HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException {
// The exampleObject will be passed back (as an attribute) to the JSP view
// The attribute will be a name/value pair, the value in this case will be a List object
request.setAttribute("exampleParameter", exampleObject);
// Forward the request to the JSP page of interest using RequestDispatcher.
request.getRequestDispatcher("/WEB-INF/example.jsp").forward(request, response);
}
}
(2) Model
public class ModelExample {
public Object getExampleObject(String key) {
...
return exampleObject
}
}
(3) JSP view (example.jsp)
<%@ page import="java...." %>
<html>
<body>
<%
Object exampleObject = (Object) request.getAttribute("exampleParameter");
...
%>
</body>
</html>
References:
http://www.datadisk.co.uk/html_docs/jsp/jsp_mvc_tutorial.htm
http://stackoverflow.com/questions/2575471/how-to-develop-jsp-servlets-web-app-using-mvc-pattern
Tuesday, 12 April 2011
SCP scripting without password
To transfer files from one unix server (Server A) to another unix server (Server B), we usually use SCP command:
scp user@ServerB:/home/user/test.txt /home/user/
However, it always prompt for password, which is very bad for scripting.
YES! There is some solution, i.e. to be authorized in the destination server. Here is step-to-step procedures to achieve this:
1. Generate public/private key pairs in home/user/.ssh in Server A:
ssh-keygen -t rsa
2. Copy id_rsa.pub in Server A to home/user/.ssh/authorized_keys2 in Server B:
scp user@ServerB:/home/user/test.txt /home/user/
However, it always prompt for password, which is very bad for scripting.
YES! There is some solution, i.e. to be authorized in the destination server. Here is step-to-step procedures to achieve this:
1. Generate public/private key pairs in home/user/.ssh in Server A:
ssh-keygen -t rsa
2. Copy id_rsa.pub in Server A to home/user/.ssh/authorized_keys2 in Server B:
scp .ssh/id_rsa.pub user@ServerB:/home/user/.ssh/authorized_keys2
The system will prompt for user password at this stage.
Note: The destination file should be authorized_keys for SSH protocol version 1, or authorized_keys2 for SSH protocol version 2.
3. Make sure that permissions for .ssh directory in both servers are set to 700.
- To view permission
ls -ld .ssh
- To change permission
chmod 700 .ssh
Done! Now SCP won't prompt password again during file copy.
For more command about file transfer using Linux or Unix, e.g. ftp, sftp, wget etc., you may visit http://aruljohn.com/info/filetransfer/
Sunday, 27 March 2011
Simple iPhone examples
Will continuously update some simple and useful iPhone examples here.
1. Logging
In Xcode, click Run > Console to see NSLog statements.
NSLog(@"log: %@", aString);
Nslog(@"log: %f", afloat);
Nslog(@"log: %i", anint);
Nslog(@"log: %f", afloat);
Nslog(@"log: %i", anint);
2. Set an image as background in UIViewController
[1] Use [UIColor colorWithPatternImage]
self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"background.png"]];
[2] Add an image view to the view, and then send the image view to background.
This method is common used and recommended.
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"background.png"]];
imageView.frame = self.view.frame;
[self.view addSubview: imageView];
[self.view sendSubviewToBack: imageView];
[imageView release];
3. Conversion between "NSString" and "char *"
[1] From NSString to char *
myString = [NSString stringWithUTF8String:myChars];
[2] From char * to NSString
myChars = [myString UTF8String];
4. Constant NSString
#define URL_SERVER @"http://www.example.com"
NSString *const URL_1 = URL_SERVER@"/a.php";
NSString *const URL_2 = URL_SERVER@"/b.php";
Friday, 12 September 2008
1+2+...+n的约数(7) - 设想:我们还可以再快吗?
是的,我们还可以再快吗?我们还可以再快吗?
答案依旧是肯定的!
我们还有可以提高100甚至更多倍的质数求解算法!我们还有”避免重复运算“的重量级武器!
没有coding是完美的,没有做不到的,只有想不到的!
废话少说,让我们分析一下吧:
1. 质数的求解速度我们可以提高!特别是在更大的约数个数需求的时候。
我们可以预先用优化后的求解算法标记出某个范围以内的质数(用mark变量),然后再需要的时候适当夸大这个运算范围(例如先10000以内,然后[10000, 20000]以内,等等)。当然我们仅仅把需要的质数放在primes的Array里。
不过,这需要很好的控制。
2. 我们并不需要特别地求解质数
注意一下,你就会发现,求解约数的过程和求解质数的过程很相似。
其实,它根本就包含着求解质数的过程。
我们可以省去那一部分的计算!3. 重复计算?
是的!还有重复计算!
在num_of_divs_ex函数里,我们可以用循环求解并保存中间的值!
4. 我们可以换种思路吗?
当一种算法山穷水尽的时候,我们可以换种思路吗?
既然求约数个数的过程和求解质数的过程很像,那我们是不是可以用求解质数的优化算法来计算约数个数呢?
我们还可以再快吗?
答案依旧是肯定的!
我们还有可以提高100甚至更多倍的质数求解算法!我们还有”避免重复运算“的重量级武器!
没有coding是完美的,没有做不到的,只有想不到的!
废话少说,让我们分析一下吧:
1. 质数的求解速度我们可以提高!特别是在更大的约数个数需求的时候。
我们可以预先用优化后的求解算法标记出某个范围以内的质数(用mark变量),然后再需要的时候适当夸大这个运算范围(例如先10000以内,然后[10000, 20000]以内,等等)。当然我们仅仅把需要的质数放在primes的Array里。
代码:
def add_prime(n)
@primes << n if @mark[n]
end2. 我们并不需要特别地求解质数
注意一下,你就会发现,求解约数的过程和求解质数的过程很相似。
其实,它根本就包含着求解质数的过程。
我们可以省去那一部分的计算!
代码:
count *= 2 if (m != 1)新代码:if (m != 1)
# @mark[m] = true # 注意这里,m是个质数!!!
count *= 2
end是的!还有重复计算!
在num_of_divs_ex函数里,我们可以用循环求解并保存中间的值!
4. 我们可以换种思路吗?
当一种算法山穷水尽的时候,我们可以换种思路吗?
既然求约数个数的过程和求解质数的过程很像,那我们是不是可以用求解质数的优化算法来计算约数个数呢?
(更多的coding我就不再贴出了)
1+2+...+n的约数(6) - 重体验: 我还可以再快吗?
问题解决的时候,一切都是那么舒爽...
一直以来,写的程序都是为了在限定时间以内运行而努力。
而这次,第一次想把自己的程序速度再进一步。
嗯,回到开始的想法:去除重复运算,用memory换时间
f(n)=n(n+1)/2=n1*n2 (n1=n/2,n2=n+1或者n1=n,n2=(n+1)/2)
因为n,n+1相邻,所以n1与n2之间没有共同的质数约数
n1与n2之间没有共同的质数约数!
也就是说 f(n)的约数个数 = n1的约数个数 × n2的约数个数
而f(n)和f(n+1)都会有个共同的部分 n+1 (或(n+1)/2)
这就是说:我们可以节省这部分重复运算!
这可以节省1/2甚至更多的运算量!
coding如下
500个约数仅需要0.313s,速度提高了将近3倍...
一直以来,写的程序都是为了在限定时间以内运行而努力。
而这次,第一次想把自己的程序速度再进一步。
嗯,回到开始的想法:去除重复运算,用memory换时间
f(n)=n(n+1)/2=n1*n2 (n1=n/2,n2=n+1或者n1=n,n2=(n+1)/2)
因为n,n+1相邻,所以n1与n2之间没有共同的质数约数
n1与n2之间没有共同的质数约数!
也就是说 f(n)的约数个数 = n1的约数个数 × n2的约数个数
而f(n)和f(n+1)都会有个共同的部分 n+1 (或(n+1)/2)
这就是说:我们可以节省这部分重复运算!
这可以节省1/2甚至更多的运算量!
coding如下
代码:
class Divisor
# primes: [2, 3, 5, 7, ...]
#attr_accessor :primes, :offset, :memory
def initialize
@primes = Array.new(1, 2)
@offset = 3
@memory = Array.new
end
def n(num)
return 1 if (num == 1)
n = 2
n += 1 while (num_of_divs(n) < num)
return n
end
# add n if it is a prime
def add_prime(n)
sqrt = Math.sqrt(n).to_i
@primes.each do |prime|
break if (prime > sqrt)
return if (n % prime == 0)
end
@primes << n
end
# number of divisors of f(n) = 1 + 2 + ... + n = n(n+1)/2
def num_of_divs(n)
n1 = n
n2 = n +1
sqrt = Math.sqrt(n2).to_i
# if not added (into primes' list), try to add it,
if (sqrt >= @offset)
add_prime(sqrt)
@offset += 1 #increase prime offset
end
# f(n) = n(n+1)/2 could be as multiplication of two numbers, either (n/2) * (n+1) or n * [(n+1)/2]
if (n1 % 2 == 0)
n1 /= 2
else
n2 /= 2
end
return num_of_divs_ex(n1) * num_of_divs_ex(n2)
end
# number of divisors of n
def num_of_divs_ex(n)
return @memory[n] if @memory[n] #return if it is already stored in memory
count = 1
m = n
@primes.each do |prime|
break if (m == 1)
if @memory[m]
count *= @memory[m]
@memory[n] = count
return count
end
# check whther <prime> is one of divisor of <m>
tmp = 0
while (m % prime == 0)
tmp += 1
m /= prime
end
# update <count> if <prime> is one of divisor of <m>
count *= (tmp + 1) if (tmp > 0)
end
count *= 2 if (m != 1)
@memory[n] = count
return count
end
end
start = Time.now
div = Divisor.new
print '->' + div.n(500).to_s + '<-'
final = Time.now
cost =final - start
print 'Cost: ' + cost.to_s
Subscribe to:
Comments (Atom)