精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

速度追求:Objective-C高性能的循環

開發 后端
Cocoa編程的一個通常的任務是要去循環遍歷一個對象的集合 (例如,一個 NSArray, NSSet 或者是 NSDictionary). 這個看似簡單的問題有廣泛數量的解決方案,它們中的許多不乏有對性能方面問題的細微考慮.

Cocoa編程的一個通常的任務是要去循環遍歷一個對象的集合 (例如,一個 NSArray, NSSet 或者是 NSDictionary). 這個看似簡單的問題有廣泛數量的解決方案,它們中的許多不乏有對性能方面問題的細微考慮.

對于速度的追求

首先,是一個免責聲明: 相比其它問題而言,一個 Objective-C 方法原始的速度是你在編程時***才需要考慮的問題之一 – 區別就在于這個問題夠不上去同其它更加需要重點考慮的問題進行比較,比如說代碼的清晰度和可讀性.

但速度的次要性并不妨礙我們去理解它. 你應該經常去了解一下性能方面的考慮將如何對你正在編寫的代碼產生影響,一邊在極少數發生問題的情況下,你會知道如何下手.

還有,在循環的場景中,大多數時候不管是從可讀性或者是清晰度考慮,你選擇哪種技術都沒什么關系的, 所以你還不如選擇速度最快的那一種. 沒有必要選擇編碼速度比要求更慢的。

考慮到這一點,就有了如下的選擇:

經典的循環方式

  1. for (NSUInteger i = 0; i < [array count]; i++){  
  2.   id object = array[i];  
  3.   …} 

這是循環遍歷一個數組的一個簡單熟悉的方式; 從性能方面考慮它也相當的差勁. 這段代碼***的問題就是循環每進行一次我們都會調用數組的計數方法. 數組的總數是不會改變的,因此每次都去調用一下這種做法是多余的. 像這種代碼一般C編譯器一般都會優化掉, 但是 Objective-C 的動態語言特性意味著對這個方法的調用不會被自動優化掉. 因此,為了提升性能,值得我們在循環開始之前,將這個總數存到一個變量中,像這樣:

  1. NSUInteger count = [array count];for (NSUInteger i = 0; i < count; i++){  
  2.   id object = array[i];  
  3.   …} 

NSEnumerator

NSEnumerator 是循環遍歷集合的一種可選方式. 所有的集合都已一個或者更多個枚舉方法,每次它們被調用的時候都會返回一個NSEnumerator實體. 一個給定的 NSEnumerator 會包含一個指向集合中***個對象的指針, 并且會有一個 nextObject 方法返回當前的對象并對指針進行增長. 你可以重復調用它直到它返回nil,這表明已經到了集合的末尾了:

  1. id obj = nil;NSEnumerator *enumerator = [array objectEnumerator];while ((obj = [enumerator nextObject]));{  
  2.   …            

NSEnumerator 的性能可以媲美原生的for循環, 但它更加實用,因為它對索引的概念進行了抽象,這意味著它應用在結構化數據上,比如鏈表,或者甚至是無窮序列和數據流,這些結構中的數據條數未知或者并沒有被定義.

快速枚舉

快速枚舉是在 Objective-C 2.0 中作為傳統的NSEnumerator的更便利(并且明顯更快速) 的替代方法而引入的. 它并沒有使得枚舉類過時因為其仍然被應用于注入反向枚舉, 或者是當你需要對集合進行變更操作 (之后會更多地提到) 這些場景中.
快速枚舉添加了一個看起來像下面這樣子的新的枚舉方法:

  1. - (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state   
  2.    objects:(id *)stackbuf count:(NSUInteger)len; 

如果你正在想著“那看起來并不怎么舒服啊!”, 我不會怪你的. 但是新的方法順便帶來了一種新的循環語法, for…in 循環. 這是在幕后使用了新的枚舉方法, 并且重要的是在語法和性能上都比使用傳統的for循環或者 NSEnumerator 方法都更省心了:

  1. for (id object in array){  
  2.   …} 

枚舉塊

隨著塊的誕生,Apple加入第四個基于塊語法的枚舉機制. 這無疑比快速枚舉更加的少見, 但是有一個優勢就是對象和索引都會返回, 而其他的枚舉方法只會返回對象.

枚舉塊的另外一個關鍵特性就是可選擇型的并發枚舉 (在幾個并發的線程中枚舉對象). 這不是經常有用,取決于你在自己的循環中具體要做些什么, 但是在你正有許多工作要做,并且你并不怎么關心枚舉順序的場景下,它在多核處理器上可能會產生顯著的性能提高 (現在所有的 Mac和iOS設備都已經有了多核處理器).

基準測試

那么這些方法疊加起來會如何呢, 性能會更加的好么? 這里有一個簡單的基準測試命令行應用,比較了使用多種不同方法枚舉一個數據的性能. 我們已經在 ARC 關閉的情況下運行了它,以排除任何干擾最終結果的隱藏在幕后的保留或者排除處理. 由于是運行在一個很快的 Mac 機上面, 所有這些方法運行極快以至于我們實際上不得不使用一個存有10,000,000 (一千萬) 對象的數組來測量結果. 如果你決定在一個 iPhone 進行測試, 最明智的做法是使用一個小得多的數量!

為了編譯這段代碼:

  • 把代碼保存在一個文件中,命名為 benchmark.m

  • 在終端中編譯應用程序:
    clang -framework Foundation benchmark.m -o benchmark

  • 運行程序: ./benchmark

  1. #import <Foundation/Foundation.h> int main(int argc, const char * argv[]){  
  2.   @autoreleasepool  {  
  3.     static const NSUInteger arrayItems = 10000000;  
  4.      NSMutableArray *array = [NSMutableArray arrayWithCapacity:arrayItems];    for (int i = 0; i < arrayItems; i++) [array addObject:@(i)];  
  5.     array = [array copy];  
  6.     
  7.     CFTimeInterval start = CFAbsoluteTimeGetCurrent();  
  8.      // Naive for loop  
  9.     for (NSUInteger i = 0; i < [array count]; i++)  
  10.     {  
  11.       id object = array[i];    }   
  12.     CFTimeInterval forLoop = CFAbsoluteTimeGetCurrent();  
  13.     NSLog(@"For loop: %g", forLoop - start);  
  14.      // Optimized for loop  
  15.     NSUInteger count = [array count];    for (NSUInteger i = 0; i <  count; i++)  
  16.     {  
  17.       id object = array[i];    }   
  18.     CFTimeInterval forLoopWithCountVar = CFAbsoluteTimeGetCurrent();  
  19.     NSLog(@"Optimized for loop: %g", forLoopWithCountVar - forLoop);  
  20.      // NSEnumerator  
  21.     id obj = nil;    NSEnumerator *enumerator = [array objectEnumerator];    while ((obj = [enumerator nextObject]))  
  22.     {     }   
  23.     CFTimeInterval enumeratorLoop = CFAbsoluteTimeGetCurrent();  
  24.     NSLog(@"Enumerator: %g", enumeratorLoop - forLoopWithCountVar);  
  25.      // Fast enumeration  
  26.     for (id object in array)  
  27.     {     }   
  28.     CFTimeInterval forInLoop = CFAbsoluteTimeGetCurrent();  
  29.     NSLog(@"For…in loop: %g", forInLoop - enumeratorLoop);  
  30.      // Block enumeration  
  31.     [array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {     }];  
  32.     
  33.     CFTimeInterval enumerationBlock = CFAbsoluteTimeGetCurrent();  
  34.     NSLog(@"Enumeration block: %g", enumerationBlock - forInLoop);  
  35.      // Concurrent enumeration  
  36.     [array enumerateObjectsWithOptions:NSEnumerationConcurrent   
  37.       usingBlock:^(id obj, NSUInteger idx, BOOL *stop) {     }];  
  38.     
  39.     CFTimeInterval concurrentEnumerationBlock = CFAbsoluteTimeGetCurrent();  
  40.     NSLog(@"Concurrent enumeration block: %g",   
  41.       concurrentEnumerationBlock - enumerationBlock);  }  
  42.   return 0;} 

下面展示出了結果:

  1. $ For loop: 0.119066  
  2. $ Optimized for loop: 0.092441  
  3. $ Enumerator: 0.123687  
  4. $ For…in loop: 0.049296  
  5. $ Enumeration block: 0.295039  
  6. $ Concurrent enumeration block: 0.199684 

忽略掉時間的具體長短. 我們感興趣的是它們同其它方法比較的相對大小. 如果我們按順序排列它們,快的放前面,我會得到了下面的結果:

  1. For…in循環 – 最快.

  2. 對for循環的優化 – 比 for…in 慢兩倍.

  3. 沒有優化的for循環 – 比 for…in 慢2.5倍.

  4. Enumerator – 大約同沒有優化的循環相同.

  5. 并發的枚舉塊 – 比 for…in 大約慢6倍.

  6. 枚舉塊 – 比 for…in 幾乎慢6倍.

For…in 是勝出者. 顯然他們將其稱為快速枚舉是有原因的! 并發枚舉看起來是比單線程的快一點點, 但是你沒必要對其做更多的解讀: 我們這里是在枚舉一個非常非常大型的對象數組,而對于小一些的數據并發執行的開銷遠多于其帶來的好處.

并發執行的主要是在當你的循環需要大量的執行時間時有優勢. 如果你在自己的循環中有許多東西要運行,那就考慮試下并行枚舉,在你不關心枚舉順序的前提下 (但是請用行動的去權衡一下它是否變得更快樂,不要空手去揣度).

#p#

其它集合類型Other Collection Types

那么其它的結合類型怎么樣呢, 比如 NSSet 和 NSDictionary? NSSet 是無序的, 因此沒有按索引去取對象的概念.我們也可以進行一下基準測試:

  1. $ Enumerator: 0.421863  
  2. $ For…in loop: 0.095401  
  3. $ Enumeration block: 0.302784  
  4. $ Concurrent enumeration block: 0.390825 

結果同 NSArray 一致; for…in 再一次勝出了. NSDictionary怎么樣了? NSDictionary 有一點不同因為我們同時又一個鍵和值對象需要迭代. 在一個字典中單獨迭代鍵或者值是可以的, 但典型的情況下我們兩者都需要. 這里我們有一段適配于操作NSDictionary的基準測試代碼:

  1. #import <Foundation/Foundation.h> int main(int argc, const char * argv[]){  
  2.   @autoreleasepool  {  
  3.     static const NSUInteger dictItems = 10000;  
  4.      NSMutableDictionary *dictionary =   
  5.       [NSMutableDictionary dictionaryWithCapacity:dictItems];    for (int i = 0; i < dictItems; i++) dictionary[@(i)] = @(i);  
  6.     dictionary = [dictionary copy];  
  7.     
  8.     CFTimeInterval start = CFAbsoluteTimeGetCurrent();  
  9.      // Naive for loop  
  10.     for (NSUInteger i = 0; i < [dictionary count]; i++)  
  11.     {  
  12.       id key = [dictionary allKeys][i];      id object = dictionary[key];    }   
  13.     CFTimeInterval forLoop = CFAbsoluteTimeGetCurrent();  
  14.     NSLog(@"For loop: %g", forLoop - start);  
  15.      // Optimized for loop  
  16.     NSUInteger count = [dictionary count];    NSArray *keys = [dictionary allKeys];    for (NSUInteger i = 0; i <  count; i++)  
  17.     {  
  18.       id key = keys[i];      id object = dictionary[key];    }   
  19.     CFTimeInterval forLoopWithCountVar = CFAbsoluteTimeGetCurrent();  
  20.     NSLog(@"Optimized for loop: %g", forLoopWithCountVar - forLoop);  
  21.      // NSEnumerator  
  22.     id key = nil;    NSEnumerator *enumerator = [dictionary keyEnumerator];    while ((key = [enumerator nextObject]))  
  23.     {  
  24.       id object = dictionary[key];    }   
  25.     CFTimeInterval enumeratorLoop = CFAbsoluteTimeGetCurrent();  
  26.     NSLog(@"Enumerator: %g", enumeratorLoop - forLoopWithCountVar);  
  27.      // Fast enumeration  
  28.     for (id key in dictionary)  
  29.     {  
  30.       id object = dictionary[key];    }   
  31.     CFTimeInterval forInLoop = CFAbsoluteTimeGetCurrent();  
  32.     NSLog(@"For…in loop: %g", forInLoop - enumeratorLoop);  
  33.      // Block enumeration  
  34.     [dictionary enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {     }];  
  35.     
  36.     CFTimeInterval enumerationBlock = CFAbsoluteTimeGetCurrent();  
  37.     NSLog(@"Enumeration block: %g", enumerationBlock - forInLoop);  
  38.      // Concurrent enumeration  
  39.     [dictionary enumerateKeysAndObjectsWithOptions:NSEnumerationConcurrent   
  40.       usingBlock:^(id key, id obj, BOOL *stop) {     }];  
  41.     
  42.     CFTimeInterval concurrentEnumerationBlock = CFAbsoluteTimeGetCurrent();  
  43.     NSLog(@"Concurrent enumeration block: %g",   
  44.       concurrentEnumerationBlock - enumerationBlock);  }  
  45.   return 0;}  

NSDictionary 填充起來比 NSArray 或者 NSSet 慢得多, 因此我們把數據條數減少到了10,000 (一萬) 以避免機器鎖住. 因而你應該忽略結果怎么會比那些 NSArray 低那么多,因為我們使用的是更少對象的 1000 次循環:

  1. $ For loop: 2.25899  
  2. $ Optimized for loop: 0.00273103  
  3. $ Enumerator: 0.00496799  
  4. $ For…in loop: 0.001041  
  5. $ Enumeration block: 0.000607967  
  6. $ Concurrent enumeration block: 0.000748038 

沒有優化過的循環再這里慢得很壯觀,因為每一次我們都復制了鍵數組. 通過把鍵數組和總數存到變量中,我們獲得了更快的速度. 查找對象的消耗現在主宰了其它的因素,因此使用一個for循環, NSEnumerator 或者for…in 差別很小. 但是對于枚舉塊方法而言,它在一個方法中把鍵和值都返回了,所以現在變成了最快的選擇。

反轉齒輪

基于我們所見,如果所有其它的因素都一樣的話,在循環遍歷數組時你應該嘗試去使用for...in循環, 而遍歷字典時,則應該選擇枚舉塊. 也有一些場景下這樣的做法并不可能行得通,比如我們需要回頭來進行枚舉,或者當我們在遍歷時想要變更集合的情況.
為了回過頭來枚舉一個數據,我們可以調用reverseObjectEnumerator方法來獲得一個NSEnumerator 以從尾至頭遍歷數組. NSEnumerator, 就像是 NSArray 它自己, 支持快速的枚舉協議. 那就意味著我們仍然可以在這種方式下使用 for…in, 而無速度和簡潔方面的損失:

  1. for (id object in [array reverseObjectEnumerator])   
  2. {  
  3. …  } 

(除非你異想天開, NSSet 或者 NSDictionary 是沒有等效的方法的, 而反向枚舉一個 NSSet 或者NSDictionary無論如何都沒啥意義, 因為鍵是無序的.)

如果你想使用枚舉塊的話, NSEnumerationReverse你可以試試, 像這樣:

  1. [array enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(id obj, NSUInteger idx, BOOL *stop) {  
  2.   …  }]; 

變更Mutation

應用同樣的循環技術到變更中的集合上是可能的; 其性能也大致相同. 然而當你嘗試在循環數組或者字典的時候修改它們,你可能經常會面臨這樣的異常:

  1. '*** Collection XYZ was mutated while being enumerated.' 

就像我們優化了的for循環, 所有這些循環技術的性能取決于事先把數據總數存下來,這意味著如果你開始在循環中間加入或者去掉一個數據時,這個數據就不正確了. 但是在循環進行中加入,替換或者移除一條數據時經常想要做的事情. 那么什么才是這個問題的解決之道呢?

我們經典的for循環可以工作得很好,因為它不依賴于駐留的總數常量; 我們只需要記得,如果我們添加或者移除了一條數據,就要增加或者減小索引. 但我們已經了解到for循環并不是一種速度快的解決方案. 我們優化過的for循環則是一個合理的選擇, 只要我們記得按需遞增或者遞減技術變量,還有索引.

我們仍然可以使用for…in, 但前提是我們首先創建了一個數組的拷貝. 這會起作用的,例如:

  1. for (id object in [array copy])   
  2.  {  
  3.    // Do something that modifies the array, e.g. [array removeObject:object];  
  4.  } 

如果我們對不同的技術進行基準測試(必要時把復制數組的開銷算在內,以便我們可以對原來數組內的數據進行變更), 我們發現復制抵消了 for…in 循環之前所擁有的好處:

  1. $ For loop: 0.111422  
  2. $ Optimized for loop: 0.08967  
  3. $ Enumerator: 0.313182  
  4. $ For…in loop: 0.203722  
  5. $ Enumeration block: 0.436741  
  6. $ Concurrent enumeration block: 0.388509 

在我們遍歷一個數組時修改這個數組最快的計數,似乎是需要使用一個優化了的for循環的.

對于一個 NSDictionary, 我們不需要為了使用NSEnumerator 或者快速枚舉而復制整個字典; 我們可以只去使用allKeys方法獲取到所有鍵的一個副本. 這都將能很好的運作起來:

  1. // NSEnumerator  
  2.   id key = nil;  NSEnumerator *enumerator = [[items allKeys] objectEnumerator];  while ((key = [enumerator nextObject]))  
  3.   {  
  4.     id object = items[key];    // Do something that modifies the value, e.g. dictionary[key] = newObject;  
  5.   }   // Fast enumeration  
  6.   for (id key in [dictionary allkeys])   
  7.   {  
  8.     id object = items[key];    // Do something that modifies the value, e.g. dictionary[key] = newObject;  
  9.   } 

然而同樣的技術在使用enumerateKeysAndObjectsUsingBlock方法時并不能起作用. 如果我們循環遍歷一個字典進行基準測試, 按照需要對鍵或者對字典整體創建備份,我們得到了下面的結果:

  1. $ For loop: 2.24597  
  2. $ Optimized for loop: 0.00282001  
  3. $ Enumerator: 0.00508499  
  4. $ For…in loop: 0.000990987  
  5. $ Enumeration block: 0.00144804  
  6. $ Concurrent enumeration block: 0.00166804 

這里我們可以看到 for…in 循環是最快的一個. 那是因為在for...in循環中根據鍵取對象的開銷現在已經被在調用枚舉塊方法之前復制字典的開銷蓋過去了.

當枚舉一個NSArray的時候:

  • 使用 for (id object in array) 如果是順序枚舉

  • 使用 for (id object in [array reverseObjectEnumerator]) 如果是倒序枚舉

  • 使用 for (NSInteger i = 0; i < count; i++) 如果你需要知道它的索引值,或者需要改變數組

  • 嘗試 [array enumerateObjectsWithOptions:usingBlock:] 如果你的代碼受益于并行執行

當枚舉一個NSSet的時候:

  • 使用  for (id object in set) 大多數時候

  • 使用 for (id object in [set copy]) 如果你需要修改集合(但是會很慢)

  • 嘗試 [array enumerateObjectsWithOptions:usingBlock:] 如果你的代碼受益于并行執行

當枚舉一個NSDictionary的時候:

  • 使用  for (id object in set) 大多數時候

  • 使用 for (id object in [set copy]) 如果你需要修改詞典

  • 嘗試 [array enumerateObjectsWithOptions:usingBlock:] 如果你的代碼受益于并行執行

這些方法可能不是最快的,但他們都是非常清晰易讀的。所以請記住,有時是在不寫干凈的代碼,和快速的代碼之間做出選擇,你會發現,你可以在兩個世界得到***的。

英文原文:Tips for High Performance Collection Looping in Objective-C

譯文鏈接:http://www.oschina.net/translate/high-performance-collection-looping-objective-c

責任編輯:林師授 來源: 中國開源社區編譯
相關推薦

2011-08-10 18:07:29

Objective-C反射

2013-03-27 12:54:00

iOS開發Objective-C

2013-06-20 10:40:32

Objective-C實現截圖

2011-05-11 15:58:34

Objective-C

2011-05-11 11:20:26

Objective-C

2014-11-25 10:18:17

Objective-C

2014-07-29 09:44:35

2013-04-11 13:41:30

Objective-CiOS編程

2011-08-04 11:15:46

Objective-C 構造函數 構造方法

2011-05-11 13:54:08

Objective-C

2011-05-11 14:06:49

Objective-C

2011-05-11 15:45:50

內存管理Objective-C

2011-08-04 14:58:37

Objective-C Cocoa NSString

2013-08-21 14:57:42

objective-c問題

2011-08-02 13:16:36

Objective-C 語法 函數

2011-07-08 13:49:46

Objective-C UUID

2011-08-17 10:58:59

Objective-C構造函數

2012-03-07 13:43:59

Objective-C

2011-08-03 16:55:05

Objective-C 代理

2011-07-29 16:16:30

Objective-c block
點贊
收藏

51CTO技術棧公眾號

中文字幕av网址| 免费超爽大片黄| 亚洲字幕av一区二区三区四区| 久久综合99| 欧美大片一区二区| 国产精品久久毛片av大全日韩| 欧美激情喷水视频| 免费看污片网站| 精品视频在线一区| 黑人欧美xxxx| 色爽爽爽爽爽爽爽爽| 婷婷国产在线| 久久99国产精品免费| 午夜欧美大片免费观看| 顶级黑人搡bbw搡bbbb搡| 精品伊人久久久| 欧美丰满少妇xxxxx高潮对白| 国产欧美日韩网站| 中文字幕在线视频区| 成人午夜又粗又硬又大| 国产乱肥老妇国产一区二| 日本中文字幕免费| 亚洲午夜精品一区 二区 三区| 精品亚洲一区二区三区四区五区| 超碰在线免费av| 欧美成人精品三级网站| 五月开心婷婷久久| 黄黄视频在线观看| 91高清在线| 久久久综合网站| 国产精品一区视频网站| 国产又粗又猛又色又| 久久久亚洲一区| 午夜欧美不卡精品aaaaa| 国产十六处破外女视频| 欧美成人milf| 中文字幕国产亚洲2019| aa片在线观看视频在线播放| 99精品在免费线中文字幕网站一区| 欧美日韩国产大片| 国产又猛又黄的视频| 色是在线视频| 黄网动漫久久久| 奇米影视亚洲色图| 日韩三级电影视频| 亚洲美女视频在线观看| 在线观看日韩羞羞视频| 中文字幕在线视频区| 国产欧美日韩在线观看| 欧美日韩国产一二| 免费一级在线观看| 久久婷婷成人综合色| 国产一区免费在线| 天天爱天天干天天操| 国产91富婆露脸刺激对白| 亚洲在线www| 国产草草影院ccyycom| 久88久久88久久久| 亚洲在线观看视频网站| 成人高潮片免费视频| 国产成人av电影在线观看| a级国产乱理论片在线观看99| 国产成a人亚洲精v品无码| 国产成人a级片| 国产精品免费一区二区三区四区 | av色图一区| 国产精品热久久久久夜色精品三区| 视频一区二区三区免费观看| av黄色在线观看| ...中文天堂在线一区| 激情视频小说图片| bl视频在线免费观看| 天天色天天操综合| 无码日韩人妻精品久久蜜桃| 国产激情欧美| 日韩一级片网站| 中文字幕一区二区三区乱码不卡| 色老板在线视频一区二区| 亚洲欧美国产va在线影院| 国产传媒视频在线| 女同性一区二区三区人了人一 | 另类激情视频| 欧美三级电影网| 99九九精品视频| 国产精东传媒成人av电影| 日韩精品在线第一页| 我不卡一区二区| 综合av在线| 欧美亚洲国产日本| 97精品人妻一区二区三区| 成人免费视频视频| 水蜜桃亚洲精品| 乱插在线www| 欧美综合天天夜夜久久| 国产sm在线观看| 啪啪亚洲精品| 欧美激情国产高清| 艳妇乳肉豪妇荡乳av无码福利 | 成人av影视在线| 欧美性孕妇孕交| 亚洲品质自拍视频网站| 内射国产内射夫妻免费频道| 四虎影视国产精品| 日韩精品免费在线观看| 最新一区二区三区| 午夜一区不卡| www 成人av com| 91精品大全| 欧美性xxxx| 台湾佬美性中文| 日韩免费av| 午夜精品福利电影| 国产日韩精品suv| 91麻豆蜜桃一区二区三区| 吴梦梦av在线| 成人免费看视频网站| 日韩精品一区二区三区四区视频| 性欧美一区二区| 国产日本精品| 国产精品二区在线| 二区在线播放| 欧美日韩精品三区| 欧美大波大乳巨大乳| 日韩亚洲国产精品| 痴汉一区二区三区| 国产二区三区在线| 欧美日韩黄色影视| 亚洲精品国产91| 国产日韩欧美一区在线| 91久久精品一区二区别| 欧美性天天影视| 欧美视频一区二区三区四区| 法国空姐电影在线观看| 夜夜嗨一区二区| 国产日韩欧美精品| 国产黄色大片在线观看| 欧美mv日韩mv国产| 久热这里只有精品在线| 国产在线精品免费| 中文字幕在线中文字幕日亚韩一区| 电影久久久久久| 国产香蕉97碰碰久久人人| 日本天堂网在线| 91浏览器在线视频| 久久网站免费视频| 免费看日本一区二区| 人人澡人人澡人人看欧美| 免费一级在线观看| 在线亚洲免费视频| 欧美一区二区三区粗大| 日本vs亚洲vs韩国一区三区二区| 日韩精品国内| 国外成人福利视频| 久久精品亚洲热| av中文字幕播放| 亚洲国产日产av| 免费黄色三级网站| 亚洲在线日韩| 欧美一区二区三区成人久久片 | 国产熟女一区二区| 日韩1区2区3区| 亚洲欧美成人一区| 成人av在线播放| 欧美黑人又粗大| 五月婷婷在线观看视频| 一本色道久久综合亚洲91| 色欲狠狠躁天天躁无码中文字幕 | 国产日韩欧美在线观看| 黄色在线免费| 欧美精品一区男女天堂| 日本高清不卡码| 国产精品婷婷午夜在线观看| www.com久久久| 亚洲手机视频| 日韩福利二区| 精品午夜av| 97国产精品人人爽人人做| 国产在线视频网| 3751色影院一区二区三区| 久久久精品国产sm调教| 久久久久久黄色| 在线看免费毛片| 最新国产乱人伦偷精品免费网站| 欧美日韩一区二区视频在线观看| 欧美美女被草| 国语自产在线不卡| av网站大全在线观看| 精品久久久久久久久久久院品网| 丁香六月婷婷综合| ●精品国产综合乱码久久久久| 完美搭档在线观看| 麻豆成人久久精品二区三区小说| 久久久久久久久久伊人| 妖精视频一区二区三区免费观看| 成人在线视频网| 伊人网在线播放| 另类图片亚洲另类| 成人精品一区二区三区校园激情| 日韩欧美国产精品| 中文字幕在线播放不卡| 亚洲大片在线观看| 天堂а√在线中文在线鲁大师| 成人激情小说乱人伦| www.久久久精品| 一区二区国产精品| 影音先锋男人的网站| 久久爱www成人| 国产精品美女诱惑| 精品视频在线观看免费观看| 国产精品国产三级国产aⅴ浪潮| 美足av综合网| 久久精品在线视频| 好男人免费精品视频| 精品国产亚洲在线| 国产美女明星三级做爰| 欧美又粗又大又爽| 国产精品一区二区三区四| 亚洲一区日韩精品中文字幕| 侵犯稚嫩小箩莉h文系列小说| 久久精品无码一区二区三区| 一级少妇精品久久久久久久| 精品无人区卡一卡二卡三乱码免费卡 | 4444kk亚洲人成电影在线| 激情久久99| 国产精品第二页| 成人av观看| 欧美亚洲在线视频| 99thz桃花论族在线播放| 久久国产精品电影| 毛片av在线| 深夜福利日韩在线看| 国产在线一二三区| 亚洲欧美中文另类| 亚洲欧美自偷自拍| 亚洲国产私拍精品国模在线观看| 亚洲福利在线观看视频| 91麻豆精品国产自产在线| 国产一区二区在线视频观看| 精品视频123区在线观看| 久久久精品毛片| 91国产丝袜在线播放| 香蕉影院在线观看| 色悠久久久久综合欧美99| 五月婷婷中文字幕| 丰满岳妇乱一区二区三区| 九九热在线视频播放| 狠狠久久五月精品中文字幕| 五月婷婷视频在线| 在线观看一区二区视频| 波多野结衣人妻| 欧美日韩免费高清一区色橹橹 | 国产在线视频一区二区| 精品国产鲁一鲁一区二区三区| 国产制服丝袜一区| 日批视频在线看| 国产成人av电影在线观看| 一级黄色电影片| www.亚洲色图.com| 亚洲成人网在线播放| 久久精品人人做人人爽97| 欧美福利第一页| 亚洲欧美aⅴ...| 久久影院一区二区| 狠狠躁夜夜躁久久躁别揉| 亚洲天堂一区在线| 欧美日韩中文国产| 国产女人高潮毛片| 亚洲精品一区在线观看| 欧美偷拍视频| 精品国产一区久久久| 青春草视频在线| 77777少妇光屁股久久一区| 亚洲精品在线影院| 99视频免费观看| 亚洲瘦老头同性70tv| 亚洲精品中文字幕在线| 欧美91福利在线观看| 97国产在线播放| 国产自产视频一区二区三区| 国产精品久久久久久在线观看| 久久综合资源网| 免费高清在线观看电视| 亚洲成国产人片在线观看| 探花国产精品一区二区| 日韩欧美国产一区二区在线播放| 欧美成熟毛茸茸| 久精品免费视频| 欧美精品高清| 操一操视频一区| 不卡在线一区| 美女扒开大腿让男人桶| 日本欧美在线看| wwwxx日本| 日韩理论片网站| 9i看片成人免费看片| 日韩一区二区影院| 国产中文在线| 午夜精品久久久久久久男人的天堂 | 一级黄色大片免费看| 国产日韩三级在线| 精品在线视频观看| 欧美日韩你懂的| 天天干天天摸天天操| 久久精品国产99国产精品澳门 | 国产欧美中文字幕| 麻豆一区二区| 亚洲av综合色区| 蜜桃av噜噜一区| 黄瓜视频污在线观看| 亚洲资源在线观看| 99精品在线视频观看| 国产性猛交xxxx免费看久久| 国产在线看片免费视频在线观看| 91在线视频一区| 北条麻妃国产九九九精品小说| 亚洲 自拍 另类小说综合图区| 精品写真视频在线观看| 91在线无精精品白丝| 色综合久久88色综合天天免费| 成人精品在线播放| 久久亚洲成人精品| 青青久久精品| 日韩欧美三级一区二区| 亚洲永久网站| 成年人网站免费在线观看| 亚洲成a人片在线观看中文| www天堂在线| 另类专区欧美制服同性| 99久久这里有精品| 日韩视频在线免费播放| 免费在线欧美视频| 三年中国中文观看免费播放| 欧美性高跟鞋xxxxhd| 亚洲 精品 综合 精品 自拍| 性欧美暴力猛交69hd| 永久免费精品视频| www.欧美黄色| 成人激情视频网站| 久久视频免费在线观看| 欧美第一区第二区| 密臀av在线| 精品一区二区三区自拍图片区| 亚洲国产国产亚洲一二三| 天天躁日日躁狠狠躁免费麻豆| 亚洲国产精品久久人人爱| 性生活黄色大片| 久久全国免费视频| 噜噜噜狠狠夜夜躁精品仙踪林| 伊人成色综合网| 久久精品在这里| 免费精品一区二区| 色青青草原桃花久久综合| 色狠狠一区二区三区| 国产大尺度在线观看| 国产高清久久久| 国产午夜福利一区二区| 日韩成人在线视频| 2019年精品视频自拍| 一区二区三区我不卡| 国产自产2019最新不卡| 青青草原在线免费观看视频| 精品国产a毛片| 无遮挡在线观看| 亚洲欧美久久234| 国产精品一级在线| 日韩三级视频在线| 亚洲色在线视频| 亚洲网站免费| 免费拍拍拍网站| 久久精品人人爽人人爽| 国产免费黄色录像| 国内精品久久久久久| 国产91精品对白在线播放| 粉色视频免费看| 午夜激情综合网| www.av在线播放| 91丨九色丨国产| 免费亚洲婷婷| 黄色录像免费观看| 亚洲激情视频在线| 3d欧美精品动漫xxxx无尽| 懂色av一区二区三区四区五区| 成人av网站在线观看| 国产精品免费无遮挡无码永久视频| 日韩最新免费不卡| 日韩伦理一区二区三区| 在线不卡一区二区三区| 亚洲综合在线观看视频| 二区三区在线| 国产精品日韩一区二区三区| 人人超碰91尤物精品国产| 久久黄色小视频| 中文字幕在线亚洲| 欧美亚洲色图校园春色| 伊人色在线视频| 色综合久久六月婷婷中文字幕| 暖暖日本在线观看| 久久亚洲免费| 粉嫩一区二区三区在线看| 中文字幕欧美色图|