通過Enumeration和Iterator遍歷Hashtable的效率分析

今天需要遍歷壹個Hashtable,查看了壹下Hashtable類,發現它提供了如下幾個方法可供我們遍歷:

  keys() – returns an Enumeration of the keys of this Hashtable

  keySet() – returns a Set of the keys

  entrySet() – returns a Set of the mappings

  elements() – returns an Enumeration of the values of this Hashtable

  4種方法,那種更好呢,寫段代碼來比較壹下吧:

  import java.util.Enumeration;

  import java.util.Hashtable;

  import java.util.Iterator;

  import java.util.Map.Entry;

  public class traveseHashTable {

  public static void main(String[] args) {

  Hashtable<String, String> ht = new Hashtable<String, String>();

  for (int i = 0; i < 10000; i++) {

  ht.put(“Key=” + i, “Val=” + i);

  }

  // 1. Enumeration

  long start = System.currentTimeMillis();

  Enumeration<String> en = ht.keys();

  while (en.hasMoreElements()) {

  en.nextElement();

  }

  long end = System.currentTimeMillis();

  System.out.println(“Enumeration keys costs ” + (end – start)

  + ” milliseconds”);

  // 2. Enumeration

  start = System.currentTimeMillis();

  Enumeration<String> en2 = ht.elements();

  while (en2.hasMoreElements()) {

  en2.nextElement();

  }

  end = System.currentTimeMillis();

  System.out.println(“Enumeration elements costs ” + (end – start) + ” milliseconds”);

  // 3. Iterator

  start = System.currentTimeMillis();

  Iterator<String> it = ht.keySet().iterator();

  while (it.hasNext()) {

  it.next();

  }

  end = System.currentTimeMillis();

  System.out.println(“Iterator keySet costs ” + (end – start) + ” milliseconds”);

  // 4. Iterator

  start = System.currentTimeMillis();

  Iterator<Entry<String, String>> it2 = ht.entrySet().iterator();

  while (it2.hasNext()) {

  it2.next();

  }

  end = System.currentTimeMillis();

  System.out.println(“Iterator entrySet costs ” + (end – start) + ” milliseconds”);

  }

  }

  這裏創建了壹個10000個元素的Hashtable來供我們遍歷,打印出結果如下:

  Enumeration keys costs 6 milliseconds

  Enumeration elements costs 5 milliseconds

  Iterator keySet costs 10 milliseconds

  Iterator entrySet costs 10 milliseconds

  我們看到,通過叠代來遍歷比枚舉要多花盡壹倍的時間。所以建議大家最好通過枚舉類來遍歷Hashtable哦。

Killtest NS0-101 最新考題更新

科目編號:NS0-101
科目名稱:NetApp Accredited Sales Professional Exam
考題數目:50 Q&As

Killtest 題庫網NS0-101考試發生更新,題庫數目變為50題,
考試版本為V8.02.
有需要的客戶請聯繫客服或者直接購買,保證一次性通過考試。凡在killtest 題庫網購買題庫的客戶如果沒有通過考試,我們將全額退款。

1.Where do you go to find the latest training and events?
A.NetApp Partner.Wiki
B.NetApp Live
C.NetApp Field Portal
D.Partner Academy
Answer:C
2.What are the three most popular Partner resources?(Choose three)
A.NetApp Field Portal
B.NetApp Live
C.Partner Academy
D.NetApp GetSuccessful Partner Enablement Program
E.NetApp University Learning Center(Learning@App)
Answer:A,D,E
3.In the NetApp Value Theme, which three promises does NetApp make to your customer?(Choose three)
A.NetApp delivers value, speed, and emciency to help customers reduce cost and complexity.
B.NetApp enables greater emciency by using faster hardware devices.
C.NetApp enables breakthroughs by helping customers change the way they conduct business.
D.NetApp promises to create an outstanding customer experience.
E.NetApp promises to replace a customer’s existing infrastructure with better hardware and software.
Answer:A,C,D
4.If your customers are thinking about moving to a virtualized infrastructure, they should be interested in which two features?(choose two)
A.A tightly secured storge environment to protect critical business data.
B.Reduced infrastructure complexity to respond more nimbly to changing business requirements.
C.Increasing the number of IT personnel to manage the demands of the infrastructure
D.Having fewer application servers and the management costs associated with them.
E.Increasing storage capacity within their application-based silos.
Answer:A,B
5.Which two groups of features of Data ONTAP are used for data protection?(choose two)
A.SnapVault, SnapManager, SnapRestore
B.SnapRecover, FilexClone, Snapshot technology
C.Deduplication, SnapRestore, FlexClone
D.Snapshot technology, SnapLock, MetroCluster
E.Thin provisioning, Snapshot technology, vitualization
Answer:A,D

linux下非阻塞的tcp研究

這是根據自己的筆記整理的,如有錯誤,歡迎指出來.   tcp協議本身是可靠的,並不等於應用程序用tcp發送數據就壹定是可靠的.不管是否阻塞,send發送的大小,並不代表對端recv到多少的數據.   在阻塞模式下,send函數的過程是將應用程序請求發送的數據拷貝到發送緩存中發送並得到確認後再返回.但由於發送緩存的存在,表現為:如果發送緩存大小比請求發送的大小要大,那麽send函數立即返回,同時向網絡中發送數據;否則,send向網絡發送緩存中不能容納的那部分數據,並等待對端確認後再返回(接收端只要將數據收到接收緩存中,就會確認,並不壹定要等待應用程序調用recv);   在非阻塞模式下,send函數的過程僅僅是將數據拷貝到協議棧的緩存區而已,如果緩存區可用空間不夠,則盡能力的拷貝,返回成功拷貝的大小;如緩存區可用空間為0,則返回-1,同時設置errno為EAGAIN.   linux下可用sysctl -a | grep net.ipv4.tcp_wmem查看系統默認的發送緩存大小:   net.ipv4.tcp_wmem = 4096 16384 81920   這有三個值,第壹個值是socket的發送緩存區分配的最少字節數,第二個值是默認值(該值會被net.core.wmem_default覆蓋),緩存區在系統負載不重的情況下可以增長到這個值,第三個值是發送緩存區空間的最大字節數(該值會被net.core.wmem_max覆蓋).   根據實際測試,如果手工更改了net.ipv4.tcp_wmem的值,則會按更改的值來運行,否則在默認情況下,協議棧通常是按net.core.wmem_default和net.core.wmem_max的值來分配內存的.   應用程序應該根據應用的特性在程序中更改發送緩存大小:   socklen_t sendbuflen = 0;   socklen_t len = sizeof(sendbuflen);   getsockopt(clientSocket, SOL_SOCKET, SO_SNDBUF, (void*)&sendbuflen, &len);   printf(“default,sendbuf:%d\n”, sendbuflen);   sendbuflen = 10240;   setsockopt(clientSocket, SOL_SOCKET, SO_SNDBUF, (void*)&sendbuflen, len);   getsockopt(clientSocket, SOL_SOCKET, SO_SNDBUF, (void*)&sendbuflen, &len);   printf(“now,sendbuf:%d\n”, sendbuflen);   需要註意的是,雖然將發送緩存設置成了10k,但實際上,協議棧會將其擴大1倍,設為20k.   ——————-實例分析———————-   在實際應用中,如果發送端是非阻塞發送,由於網絡的阻塞或者接收端處理過慢,通常出現的情況是,發送應用程序看起來發送了10k的數據,但是只發送了2k到對端緩存中,還有8k在本機緩存中(未發送或者未得到接收端的確認).那麽此時,接收應用程序能夠收到的數據為2k.假如接收應用程序調用recv函數獲取了1k的數據在處理,在這個瞬間,發生了以下情況之壹:   A. 發送應用程序認為send完了10k數據,關閉了socket:   發送主機作為tcp的主動關閉者,連接將處於FIN_WAIT1的半關閉狀態(等待對方的ack),並且,發送緩存中的8k數據並不清除,依然會發送給對端.如果接收應用程序依然在recv,那麽它會收到余下的8k數據(這個前題是,接收端會在發送端FIN_WAIT1狀態超時前收到余下的8k數據.),然後得到壹個對端socket被關閉的消息(recv返回0).這時,應該進行關閉.   B. 發送應用程序再次調用send發送8k的數據:   假如發送緩存的空間為20k,那麽發送緩存可用空間為20-8=12k,大於請求發送的8k,所以send函數將數據做拷貝後,並立即返回8192;   假如發送緩存的空間為12k,那麽此時發送緩存可用空間還有12-8=4k,send()會返回4096,應用程序發現返回的值小於請求發送的大小值後,可以認為緩存區已滿,這時必須阻塞(或通過select等待下壹次socket可寫的信號),如果應用程序不理會,立即再次調用send,那麽會得到-1的值,在linux下表現為errno=EAGAIN.   C. 接收應用程序在處理完1k數據後,關閉了socket:   接收主機作為主動關閉者,連接將處於FIN_WAIT1的半關閉狀態(等待對方的ack).然後,發送應用程序會收到socket可讀的信號(通常是select調用返回socket可讀),但在讀取時會發現recv函數返回0,這時應該調用close函數來關閉socket(發送給對方ack);   如果發送應用程序沒有處理這個可讀的信號,而是繼續調用send,那麽第壹次會像往常壹樣繼續填充緩存區,然後返回,但如果再次調用send,進程會收到SIGPIPE信號,該信號的默認響應動作是退出進程.   D. 交換機或路由器的網絡斷開:   接收應用程序在處理完已收到的1k數據後,會繼續從緩存區讀取余下的1k數據,然後就表現為無數據可讀的現象,這種情況需要應用程序來處理超時.壹般做法是設定壹個select等待的最大時間,如果超出這個時間依然沒有數據可讀,則認為socket已不可用.   發送應用程序會不斷的將余下的數據發送到網絡上,但始終得不到確認,所以緩存區的可用空間持續為0,這種情況也需要應用程序來處理.   如果不由應用程序來處理這種情況超時的情況,也可以通過tcp協議本身來處理,具體可以查看sysctl項中的:   net.ipv4.tcp_keepalive_intvl   net.ipv4.tcp_keepalive_probes   net.ipv4.tcp_keepalive_time   所以,要想編寫優秀的socket程序也是很不容易的.特別是在為應用做優化時,很多工作都非常的煩瑣.