Trying on Java 8 Stream Parallel

I had been trying on Java 8 Stream Parallel.

Refer following code:

import java.util.*;
public class Test {
	public static void main(String args[]) {
		List list = new ArrayList<>();
		list.add(new Employee("First", "YongHao"));
		list.add(new Employee("Second", "YongHao"));
		list.add(new Employee("Third", "YongHao"));
		
		list.stream().sorted((e1, e2) -> e1.getFirstName().compareTo(e2.getFirstName()))
		        .forEach(System.out::println);
		
		System.out.println("--------------");
		
		list.stream().parallel().sorted(Comparator.comparing(e -> e.getFirstName()))
		        .forEachOrdered(System.out::println);
		        
		        
	}
	
	public static class Employee {
		String firstName;
		String lastName;
		public Employee(String firstName, String lastName) {
			this.firstName = firstName;
			this.lastName = lastName;
		}
		public String getFirstName() {
			return firstName;
		}
		public String getLastName() {
			return lastName;
		}
		public String toString() {
			return firstName + " " + lastName;
		}
	}
}

The result will be:
➜ java2 javac Test.java
➜ java2 java Test
First YongHao
Second YongHao
Third YongHao
————–
First YongHao
Second YongHao
Third YongHao

Look at first:

list.stream().sorted((e1, e2) -> e1.getFirstName().compareTo(e2.getFirstName()))
.forEach(System.out::println);

It first returns the list as a stream, sort the list using the lambda expression and then iterating the list and print its output.

Look at second:

list.stream().parallel().sorted(Comparator.comparing(e -> e.getFirstName()))
.forEachOrdered(System.out::println);

Notice, after returned stream-ed list, there is a chained parallel(), which will actually doing background task distribution fully utilizing your system cores. And notice, forEachOrdered method at the end, which guarantees the ordered result be returned. If we replace forEachOrdered to forEach, you will see random order be returned. Because forEach method cannot guarantee ordered result when doing parallel operation.

Another note, see the chained operation, from the list, to stream(), parallel(), sorted(), at the point Java had not yet execute anything, list.stream() did return a stream-ed list, or more formally, a lazy list, the actual execution started when we call forEach or forEachOrdered function.

I did some simple benchmark to measure the speed for these two, one without parallel and one with parallel.

Here come modified code:

import java.util.*;
public class Test {
	public static void main(String args[]) {
		List list = new ArrayList<>();
		generateList(list);
		long start = System.currentTimeMillis();
		list.stream().sorted((e1, e2) -> e1.getFirstName().compareTo(e2.getFirstName()))
		        .toArray();
		System.out.println("Elapsed:"+(System.currentTimeMillis() - start));
		System.out.println("--------------");
		start = System.currentTimeMillis();
		list.stream().parallel().sorted(Comparator.comparing(e -> e.getFirstName()))
		        .toArray();
		System.out.println("Elapsed:"+(System.currentTimeMillis() - start));        
	}
	
	private static void generateList(List list) {
		for(int i = 0; i < 2000000; i++) {
			Employee e = new Employee("EMP" + i, "YONGHAO");
			list.add(e);
		}
	}
	
	public static class Employee {
		String firstName;
		String lastName;
		public Employee(String firstName, String lastName) {
			this.firstName = firstName;
			this.lastName = lastName;
		}
		public String getFirstName() {
			return firstName;
		}
		public String getLastName() {
			return lastName;
		}
		public String toString() {
			return firstName + " " + lastName;
		}
	}
}

The result will be:
java2 javac Test.java
➜ java2 java Test
Elapsed:1901
--------------
Elapsed:337
➜ java2 java Test
Elapsed:296
--------------
Elapsed:494
➜ java2
➜ java2 java Test
Elapsed:288
--------------
Elapsed:1425
➜ java2
➜ java2 java Test
Elapsed:1834
--------------
Elapsed:422

OK, the result showed that... well, most of the time parallel operation faster, actually it should be faster when operating quite big data. Because it distributes the tasks to multiple cores.

OK, conclusion, worth to learn this new technology.

Stream and Lambda is the new features added in Java 8. A lot more to explore.

Linode Account Balance Enquiry API

Linode is a cloud hosting platform provides varieties of Linux based OS (ubuntu, cent-os, and more). It does provide an API to dynamically provision Linode cloud, like add new node, upgrade/downgrade plan, and account API. It does provide Prepaid service by credit card. In case you purchase $20 plan, you can pay in advance the amount stored in your account, it will be deducted every first week of month.

I owns a Linode. Normally I paid one or two months fee in advance. I have to create my own reminder or randomly remember, Oh, just need to pay Linode again. I had to log in to Linode Member Dashboard to check my account balance every time.

After 9 months of Linode experience, I began finding its API and found this API very useful, its Account Balance Enquiry API.

This simple API allows me to query my current account balance, and then compare with the threshold I define, if it is lower than the threshold, then I can receive iPhone Push Notification.

I set a Cron Job to execute the following PHP script which then send the notification. The details of setting up Push Notification for iPhone is not in this topic.

< ?php

$threshold = 20;

$api_key = '<your api key here>';
$result = json_decode(file_get_contents('https://api.linode.com/?api_key='.$api_key.'&api_action=account.info'), TRUE);


if($result['ACTION'] == 'account.info') {
	$balance = floatval($result['DATA']['BALANCE']);
	$balance = abs($balance);
	$message = 'Linode Account Balance is '.$balance;
	if($balance < $threshold) { 		$message .= ', lower than threshold '. $threshold; 	} 	sendAPN($message); } echo '1'; ?>

Titanium Mobile Performance in add-removal views

In Titanium Mobile development, there is a performance penalty when trying detach or attach View object to a Windows object in the circumstances the View object containing many child objects.

Trying to implement master detail view I have a function called showItemPage() which will create a View object, and a bunch of button and label plus event listener, and attach to this View, where this view will attach into a master Window object. If there is previous other View added into Windows object, the previous view must be detached and removed before the new View can add into Windows object. The performance penalty arisen when I create the view object, and add a lot of objects inside, and then at the last attach the View into Windows object. The solution of this problem is tricky, just move “attach View into Windows object” code into the front just after you create the View, before you adding any children object into the View.

I wonder when adding the View object into a Window object, it become very slow when View object contains many child objects, but it is very fast when initially no any child objects added inside.

Side Note: to implement this I will create an object to hold the current active item view in outer context, then check every times, if the current active item view is exist, then remove that view from the Windows object, before adding the new view created to the Window object, and then set this view to current active item view.

Sample code:

if(activeItemView != null) {
	masterWin.remove(activeItemView);
	activeItemView = null;
}
activeItemView = itemView;
masterWin.add(activeItemView);

Titanium Mobile Ipad Master Detail view

It was been very easy to use Titanium Mobile to implement Master Detail view on iPad Apps.

In computer user interface design, a master–detail interface displays a master list and the details for the currently selected item. A master area can be a form, list or tree of items, and a detail area can be a form, list or tree of items typically placed either below or next to the master area. Selecting an item from the master list causes the details of that item to be populated in the detail area.

Obviously, the master-detail interface shown in iPad is the master area located at left and detail area located at right. When the functions displays on iPhone, because of the smaller screen, master view takes up full width, and then a detail item clicked, the detail view will be opened as a new window view.

The key idea to implement in Titanium Mobile concept is that:

On iPhone, we mostly creating our master view, likely a tableview, and attach with a master window (masterWindow.add(tableView)). When click into detail item, we create new item window and then open using tab controller (Ti.currentTab.open(itemWindow)). So that when user can click “Back” button from the tab bar to go back to previous view and click to open another detail view.

On iPad, after we creating our widget, we will attach the widget to a View object, which attach to the main window object (masterView = Ti.UI.createView(); window.add(masterView)). We create another detailView and attach to the main window object (detailView = Ti.UI.createView(); window.add(detailView)). We set the width of the masterView as a certain width constant, and then we adjust detailView.left attribute to the width constant, to make it stand at the right.

On iPad, to handle orientation changes, we need to also adjust the detailView.left attribute and its width in order to fits to the screen after orientation changes. The key code here:

if(Ti.Platform.osname == 'ipad') {
  descArea.width = Ti.Platform.displayCaps.platformWidth - IPAD_DOUBLEVIEW_WIDTH;
  Ti.Gesture.addEventListener('orientationchange', function(e) {
   descArea.width = Ti.Platform.displayCaps.platformWidth - IPAD_DOUBLEVIEW_WIDTH;
  });
}

Attached the example screenshots that I capture from the demo apps I implement the master-detail view on iPad using Titanium Mobile.

20140412-180654.jpg

20140412-180715.jpg

Jobbole 伯乐在线

This is a IT related blog site and it is really useful for me, it’s glad that to recommend this site to you. (It is a Chinese medium blog)

这是 IT 性质的部落格,里头内容非常对我非常有益,因此我有必要推荐这个网站给大家。

它有一个理念我喜欢,它认为现在很多信息都是快餐式的,它希望提供读者一个较长篇,信息较全面的阅读体验。

真的,从这里可以学到很多很多东西。

Java Clone() explanation

Read A Few Notes About Java clone() Method, and my explanation to why Java clone() acts like that is being here:

1) Java clone will clone a new instance without calling constructor, as constructor is used to used in initialisation of construction of object, and the value of object may changed later, if run constructor again during clone, sure will got problem, so by initial design the clone will not call constructor.

 

SPDYing Up the Web

SPDY, a potential successor to HTTP, as it improved performance and a proven deployment strategy.

SPDY (pronounced Speedy), is an open networking protocol, developed by Google, to transport web content, it is currently used as a working base of HTTP/2. Its goal is to reduce web page load latency. It is achieved by prioritizing and multiplexing the transfer of web page subresources so that only one connection per client is required. Server push (or Resource Push) is included to actively push resources to client when the resource is available.

Technically, HTTP/1.0 requires differ connection for each request/response pairs. HTTP/1.1 started support request pipelining which contains multiple request/response pairs in one connection. Consider a web page having multiple images and css resources, only the HTML of web page returned then it get parsed to download separately the image resources. What SPDY do as a gateway between client and server is to coordinating the request and resources on behalf of clients on the server. When it received requests from client, it get the HTML of the web page, it server push the images resources to the client if available before it response the full HTML web content down to the client browser. Each SPDY endpoint also intelligent enough to keep tracks the last headers being sent and avoid to send again if it is unchanged. The content is compressed before sent.

SPDY is as a gateway situated at the high speed Internet backbone, the client make requests that passed through the SPDY gateway before it reached the external websites. SPDY mechanism is activated when both client and server supports SPDY, or fallback using HTTP otherwise.

Furthermore, the keys of SPDY are, i) Secure connection to gateway, regardless of server-side SSL support. ii) Single client-side connection across all domains. iii) Delegated DNS lookup. iv) Intelligent push. v) Caching. SPDY gateway will also been developed as Device-specific SPDY gateways and Open SPDY gateways.

Device-specific SPDY gateway such as Amazon Kindle implements its own SPDY gateway, (own SPDY client and server side), resulting simplify the vendor implementation which may bring faster browsing and as a selling point competed to others. Amazon also seem interested in data mining and advertising opportunities that come with controlling the gateway.

Server support and client support is increased significantly. Google Services such as Gmail, Google Search will use SPDY when it is available.Twitter, and open source Jetty Servers, apache mod, node.js is announced to implement SPDY. Google Chromium, possibly the latest build of Google Chrome, Mozilla Firefox, Opera is implementing as well. Facebook and WordPress is announced to implement SPDY across their hosted pages.

More information available at:
1) http://t.co/ESeVpWhi via @CACMmag
2) http://en.wikipedia.org/wiki/SPDY
3) SPDY & Secure Proxy Support in Google Chrome
4) https://github.com/igrigorik/node-spdyproxy/ (Node JS SPDY Proxy)
5) SPDY versus WebSockets
(the ideal of future is SPDY handles request/response, while WebSocket handles real time communication.)
6) WebSocket Layering over SPDY (Google Docs)
7) http://www.slideshare.net/fabianlange/the-spdy-protocol

[ 5) is talking SPDY is operating over SSL and it is secure compared with WebSocket. SPDY contains compressed GZip Headers where WebSocket does not have, which used to be parsed by firewalls to know the origin of request, less secure. 6) is talking Google proposed SPDY/3, which WebSocket Layering over SPDY, to provide faster performance and also security ]

Google I/O 2012 SPDY

iOS6 is coming

Long awaited iOS6 is coming and I had just upgraded to it for my iPhone 4 and iPad 3, everything smooth and fast and no giving me trouble.
First thing is to test the apps I deployed and all there run smoothly and faster than ever such as when turning the tab view for example, and sure it is applied to all other apps.
Second thing is to download New YouTube apps, because the old YouTube can’t found already. Apps Store apps had changed, became cover flow view, but frankly I still expect previous view at the first sight, ok, don’t worry, just passed and no harm.
Third thing is to install iOS6 on my ipad3 and open clock apps and enable Siri. Ok, I want to play Chinese now. Greet him first (oops he is man). Say good morning, he back me good morning? nine … “PM”, (gmt+8) ok, he know I am wrong, nice.
Fourth, open WordPress apps on my phone, to publish blogs, saw the built in maps is automatically using the Apple branded.
Using Siri Chinese to open Facebook apps, but “she” (Chinese is a girl) sorry that she can’t close the apps. Able to post Facebook status using Siri Chinese and English. I can open Twitter apps but cannot publish status there, I meant by using Siri.
And then after some tries, the Siri doesn’t work well, it keeps trying to said that the service is not working well would me wants to retries? By the way the iOS6 is coming, more types of devices can use Siri that brought a an unexpected or “expected” traffics that the server can’t handle well. And more over the Siri Chinese is still not intelligent enough which did not show what Apple introduction said Siri can learn from experience.
Programming in JavaScript is more fun, creating iPhone apps in Titanium Mobile not only brings native looks but also native performance which contrasted to the UIWebView JavaScript performance limit. However Safari JavaScript does have improvement stated but I didn’t have yet experienced it.
I expected Siri open API that custom apps can handle Siri Request, least based on the commands.
Another thing discovered is that whenever changes or updates on one device will be known on another device immediately. I am not sure if this is happened before. But I just first time see this when my iPad subscribe to apple Id my iPhone can get alert notification.
Initially, I waited for iOS6 download since yesterday but seem it is still not available on my phone, when go to Setting, general, software update, it still showing up to date, that’s meant it still stick to iOS5.1.1. I suspected because the cache issue, wonder if it can be solved but however I just tried restart the phones Ann’s waited for a while it is worked, iOS6 available for downloaded, I read some news recently revealed that some geographic users still could not get updates or Apple is not officially announced for the release to avoid huge traffics flowed to Apple server.