<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          【速度測(cè)試】SketchUp圖元類型判斷的速度對(duì)比

          共 4174字,需瀏覽 9分鐘

           ·

          2022-09-17 16:31

          上一篇文章[SU-2022-04]中提到,使用 typename 來(lái)判斷圖元類型,由于涉及字符串的對(duì)比,執(zhí)行效率較低,因而推薦使用 grep 或者 is_a? 方法。但是這兩種判斷方式在迭代圖元的過(guò)程中的執(zhí)行效率究竟差多少?為了解答這個(gè)問(wèn)題,本文做一個(gè)實(shí)驗(yàn)測(cè)試一下。

          一、圖元類型判斷的方法

          判斷一個(gè)圖元是否屬于某種類型有以下幾種方法,第一種方法直接判斷圖元類型,這一種方法可用的語(yǔ)法很多,至少包括以下幾種:

          #令 ent 為一個(gè)圖元puts ent.typename == "Edge"puts ent.is_a?(Sketchup::Edge)puts ent.instance_of?(Sketchup::Edge)puts Sketchup::Edge === ent

          以上均能夠判斷圖元 ent 是否是一個(gè)邊線類圖元,區(qū)別在于:第一種基于字符串的比較,等號(hào)左邊可能是 "Edge"、 "Face" 或者 "Group" 等字符串,通過(guò)和右邊的 "Edge" 對(duì)比確認(rèn) ent 是否為邊線類。余下三種都是基于ruby類的判斷,通過(guò)比較 ent 是否屬于 Sketchup::Edge 類來(lái)判斷。其中第三種方法中的 instance_of? 需要圖元必須是 Sketchup::Edge 也不能為其子類,但是對(duì)于 SketchUp 模型的情況而言,不存在上述情況,所以可以認(rèn)為是等價(jià)的。

          第二種方法是判斷其是否擁有某些成員,例如邊線類都擁有長(zhǎng)度 length 成員,平面類都擁有面積 area 成員:

          #令 ent 為一個(gè)圖元puts ent.respond_to?(:length)puts ent.methods.include?(:length)

          這種方法的好處在于其清晰的目標(biāo)導(dǎo)向性,判斷圖元類型的很大一部分原因是為了避免類型不符的圖元拋出 NoMethodError 錯(cuò)誤,從而導(dǎo)致腳本意外終止。并且,對(duì)于某些特殊的情況可以很方便的表達(dá),例如需要同時(shí)選出組件、群組和圖片這三類圖元時(shí),由于這三種圖元對(duì)象都包括 :definition 方法,所以可以直接用以下方式判斷:

          puts ent.respond_to?(:definition)

          第三種方法是直接不進(jìn)行判斷,將可能的拋出的異常用 begin rescue end 的方法來(lái)處理,這不是一個(gè)負(fù)責(zé)任的做法,但是某些時(shí)候可以用來(lái)跳過(guò)一些比較麻煩的篩選問(wèn)題。

          begin  # 不需要判斷圖元類型直接執(zhí)行rescue  # 如果報(bào)錯(cuò)了不會(huì)拋出異常而是執(zhí)行這里的代碼,這里也可以是空的end


          二、測(cè)試不同方法的運(yùn)行速度

          這三種方法具體又可以分為不同的實(shí)現(xiàn)路徑,以下選取幾種方法,分別測(cè)試以下幾段代碼,測(cè)試其執(zhí)行速度:

          #對(duì)比class的方法GC.starttz=Time.now().to_fedge_longer_than_10_meters=0Sketchup.active_model.entities.to_a.each{|ent|  if ent.class==Sketchup::Edge then    if ent.length>10.m then      edge_longer_than_10_meters+=1    end  end}puts "長(zhǎng)度大于10米的邊線圖元數(shù)量:#{edge_longer_than_10_meters}"puts "總耗時(shí):#{Time.now().to_f-tz}秒"
          #使用is_a?的方法GC.starttz=Time.now().to_fedge_longer_than_10_meters=0Sketchup.active_model.entities.to_a.each{|ent| if ent.is_a?(Sketchup::Edge) then if ent.length>10.m then edge_longer_than_10_meters+=1 end end}puts "長(zhǎng)度大于10米的邊線圖元數(shù)量:#{edge_longer_than_10_meters}"puts "總耗時(shí):#{Time.now().to_f-tz}秒"
          #對(duì)比typename的方法GC.starttz=Time.now().to_fedge_longer_than_10_meters=0Sketchup.active_model.entities.to_a.each{|ent| if ent.typename=="Edge" then if ent.length>10.m then edge_longer_than_10_meters+=1 end end}puts "長(zhǎng)度大于10米的邊線圖元數(shù)量:#{edge_longer_than_10_meters}"puts "總耗時(shí):#{Time.now().to_f-tz}秒"
          #使用grep的方法GC.starttz=Time.now().to_fedge_longer_than_10_meters=0Sketchup.active_model.entities.grep(Sketchup::Edge).each{|ent| if ent.length>10.m then edge_longer_than_10_meters+=1 end}puts "長(zhǎng)度大于10米的邊線圖元數(shù)量:#{edge_longer_than_10_meters}"puts "總耗時(shí):#{Time.now().to_f-tz}秒"
          #判斷成員的方法GC.starttz=Time.now().to_fedge_longer_than_10_meters=0Sketchup.active_model.entities.to_a.each{|ent| if ent.respond_to?(:length) then if ent.length>10.m then edge_longer_than_10_meters+=1 end end}puts "長(zhǎng)度大于10米的邊線圖元數(shù)量:#{edge_longer_than_10_meters}"puts "總耗時(shí):#{Time.now().to_f-tz}秒"
          #不使用to_a的is_a?方法GC.starttz=Time.now().to_fedge_longer_than_10_meters=0Sketchup.active_model.entities.each{|ent| if ent.is_a?(Sketchup::Edge) then if ent.length>10.m then edge_longer_than_10_meters+=1 end end}puts "長(zhǎng)度大于10米的邊線圖元數(shù)量:#{edge_longer_than_10_meters}"puts "總耗時(shí):#{Time.now().to_f-tz}秒"
          #處理異常的方法GC.starttz=Time.now().to_fedge_longer_than_10_meters=0Sketchup.active_model.entities.to_a.each{|ent| begin if ent.length>10.m then edge_longer_than_10_meters+=1 end rescue end}puts "長(zhǎng)度大于10米的邊線圖元數(shù)量:#{edge_longer_than_10_meters}"puts "總耗時(shí):#{Time.now().to_f-tz}秒"
          #使用while的方法GC.starttz=Time.now().to_fedge_longer_than_10_meters=0index=0len=Sketchup.active_model.entities.lengthwhile index<len do ent=Sketchup.active_model.entities[index] if ent.is_a?(Sketchup::Edge) then if ent.length>10.m then edge_longer_than_10_meters+=1 end end index+=1endputs "長(zhǎng)度大于10米的邊線圖元數(shù)量:#{edge_longer_than_10_meters}"puts "總耗時(shí):#{Time.now().to_f-tz}秒"


          三、測(cè)試結(jié)果

          通過(guò)運(yùn)行上一部分中的代碼,測(cè)試結(jié)果如下圖所示:


          從測(cè)試結(jié)果來(lái)看,有以下幾條結(jié)論:

          (1)使用ruby對(duì)象類型的判斷方法要比字符串判斷方法節(jié)約30%左右的時(shí)間。

          (2)在不涉及修改圖元的情況下使用 while 語(yǔ)句非但沒(méi)有提速,反而速度較慢,因次沒(méi)有必要用它替代迭代器。

          (3)判斷是否擁有成員的 respond_to? 方法速度也與判斷類型相近,因此對(duì)于上文所說(shuō)的群組組件的判斷,用此方法更為理想。

          (4)有隔離影響功能的 to_a 方法會(huì)額外增加一小部分執(zhí)行時(shí)間,因此使用 grep 方法既可以獲得較高的執(zhí)行效率,同時(shí)還可以做到隔離影響,是相對(duì)而言最合理的方法。

          (5)處理異常的 rescue 語(yǔ)句,速度低于字符串的比較,這是毫不意外的,實(shí)現(xiàn)具體功能時(shí)還是應(yīng)該盡量避免本身可控的不確定性。

          (完)



          本文編號(hào):SU-2022-05


          瀏覽 75
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  综合色网站 | 国产精品一区亚洲一区天堂 | 一区在线观看 | 色94色 欧美 setu | 婷婷国产精品视频 |