1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        【速度測試】SketchUp圖元類型判斷的速度對比

        共 4174字,需瀏覽 9分鐘

         ·

        2022-09-17 16:31

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

        一、圖元類型判斷的方法

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

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

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

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

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

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

        puts ent.respond_to?(:definition)

        第三種方法是直接不進行判斷,將可能的拋出的異常用 begin rescue end 的方法來處理,這不是一個負責任的做法,但是某些時候可以用來跳過一些比較麻煩的篩選問題。

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


        二、測試不同方法的運行速度

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

        #對比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 "長度大于10米的邊線圖元數量:#{edge_longer_than_10_meters}"puts "總耗時:#{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 "長度大于10米的邊線圖元數量:#{edge_longer_than_10_meters}"puts "總耗時:#{Time.now().to_f-tz}秒"
        #對比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 "長度大于10米的邊線圖元數量:#{edge_longer_than_10_meters}"puts "總耗時:#{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 "長度大于10米的邊線圖元數量:#{edge_longer_than_10_meters}"puts "總耗時:#{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 "長度大于10米的邊線圖元數量:#{edge_longer_than_10_meters}"puts "總耗時:#{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 "長度大于10米的邊線圖元數量:#{edge_longer_than_10_meters}"puts "總耗時:#{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 "長度大于10米的邊線圖元數量:#{edge_longer_than_10_meters}"puts "總耗時:#{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 "長度大于10米的邊線圖元數量:#{edge_longer_than_10_meters}"puts "總耗時:#{Time.now().to_f-tz}秒"


        三、測試結果

        通過運行上一部分中的代碼,測試結果如下圖所示:


        從測試結果來看,有以下幾條結論:

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

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

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

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

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

        (完)



        本文編號:SU-2022-05


        瀏覽 75
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            国产三级免费网站 | 欧美性xxxxx极品少妇 | 四虎黄色网址 | 午夜香蕉视频 | 天堂草原电视剧在线观看红桃 | 婷婷五月丁香社区 | 成人做爰无码A片韩国电影网斗生 | 新香蕉视频免费在线看 | 大香蕉免费网站 | 老师你的乳好涨好大3d漫画 |