PIXNET Logo登入

互聯網 - 大數據

跳到主文

本部落格為互聯網熱門頭條訊息管理中心

部落格全站分類:生活綜合

  • 相簿
  • 部落格
  • 留言
  • 名片
  • 3月 09 週四 201720:44
  • 死循環


文章出處
系統復雜度,是伴隨著系統的不斷進化逐漸產生的,事情的開始都是美好的。
系統的進化是件很有意思的事,不在這個行業的人不理解他們每天要用的各種軟件為何這么復雜,需要這么多的工程師沒日沒夜的加班。所以在知乎上就有了這種問題:

“為什么很多看起來不是很復雜的網站,比如 Facebook 需要大量頂尖高手來開發?”
參看網址:https://www.zhihu.com/question/20303645


前淘寶員工,《淘寶這十年》的作者子柳還在這個問題后面后面做了挺通俗的解釋。在他的答案后還有挺多答案。略過這些長篇文章的專業解釋,結論其實就是事情做大了,很多之前你認為不是問題的東西都成了問題。
作為實際參與開發IT系統的人,很多程序員有一種傾向,喜歡一切盡在掌握中的感覺。如果理解不了,參考一下時下流行的工匠精神,百科對其的定義是:

工匠們喜歡不斷雕琢自己的產品,不斷改善自己的工藝,享受著產品在雙手中升華的過程。工匠們對細節有很高要求,追求完美和極致,對精品有著執著的堅持和追求,把品質從99%提高到99.99%,其利雖微,卻長久造福于世。


技術人員往往要在實際工作中能否徹底貫徹自己對于標準的要求進行不斷地平衡,在各種工期倒排的惡劣情況下,還能不能維持對于高品質代碼的追求,還有幾天就是deadline了,測試代碼還要不要寫了,測試的覆蓋度能不能達到,用戶看不見的地方能不能做到更好。這種問題并不是軟件行業的專利,我們每天都會遇到。比如廚房里的員工有沒有嚴格遵守衛生的規章,4S店的維修技師有沒有按照廠家的規定完整的做了每一道檢查,保潔阿姨有沒有清理了所有的衛生死角,以上描述的行為最終都指向專業素質-職業道德,而在中國很多行業監管缺失的情況下演變成了看良心,靠宗教上的理念讓人相信下地獄,這里就不展開了,法律與道德還是留給社會學者去研究吧。
最初的軟件系統開始都沒有那么復雜,一開始都是簡單的。一個有幸能存活超過一年的系統,如果恰好又迎來用戶的爆發性增長,企業經營者與產品經理就會提出更多的想法讓軟件往預測的道路上走。這時有可能原來為10W用戶設計的用戶表就不能支撐了,要在業務爆發到500W用戶的時候依然能保證不算太差的登錄體驗,偶爾創業公司并沒準備好遇見到這種情況;如果業務線性增長對于技術人員倒是件好事,技術負責人能知道何時能遇到瓶頸,留給自己的時間窗還有多久,并開始進行合理的人才儲備和技術儲備,好吧,其實還是人才儲備,東西都是人做的。
盡管如此,小而美的系統仍然是厭倦了大公司各種復雜系統,流程,部門的開發者的最愛,系統的每一塊代碼都知道是用來做什么的,出了問題馬上就能推測出是在哪里出的問題。這只是個理想情況,當引以為傲的系統運行了以年為單位后,這個循環又開始了,后來者又開始往那個曾經小而美的系統上吐口水了。


文章來自微信平臺「麥芽面包」
微信公眾號「darkjune_think」
轉載請注明。
如果覺得文章有趣,微信掃二維碼關注我
(繼續閱讀...)
文章標籤

AutoPoster 發表在 痞客邦 留言(0) 人氣(7)

  • 個人分類:生活學習
▲top
  • 3月 09 週四 201720:44
  • 學點虛擬化知識


文章出處
虛擬化技術是業務發展到一定階段,互聯網企業必然會使用的技術。
互聯網業務是7*24小時運行的,系統穩定性是生命線。企業為了保障業務穩定性會使用大量服務器,如何有效的提高機器的使用率,讓好鋼用在刀刃上,對于上層業務無侵入性的虛擬化技術能幫很大忙。
線上應用各有各的特點:
  • Java應用通常對于CPU要求不高,對于內存會比較高,寫IO可能也不會很高,除非業務日志開到debug級別瘋狂的寫,這在線上是不大可能的。最后對磁盤容量要求很低。


  • 跑數據庫的軟件,一般CPU也不會很高,對于內存和IO要求會很高,IO要求要遠高于Java應用。內存需求一般是由于數據庫引擎會盡量將常用數據緩存在內容中提高性能,所以有時候把整張表都放在內存中也是可能,這就要求盡量高的內存。IO更不必說,主要是可能會有大量寫,畢竟數據庫就是一個保存狀態的實體,不可避免的要有大量的狀態需要保存。


  • 實時流式計算類,Storm,Spark啥的,通常由于其處理數據的場景會導致吞吐量較大,CPU必然會消耗較大。


  • 離線計算類,Hadoop, 數倉,BI,都是數據處理類,此類應用使用的高峰期有可能是半夜才剛開始。


  • 以上幾種典型應用,可以想象一下,如果同類型的應用都放在同一個集群上,是一種比較大的浪費,web應用的使用是隨著人走的,人睡覺了,系統的低峰期就來了,半夜CPU都是閑置的,電還是一樣用著;而全是Hadoop的集群半夜才開始吭哧吭哧的處理數據分析的業務;一種很自然的想法就是在集群中去混部各種業務,讓優勢互補,讓機器一直保持在有事干的狀態。
    混部當然也有一些問題,例如同一臺物理機上A應用被B應用突來的高峰所影響,CPU周期被搶光,莫名其妙的負載升高。混部有時也不是一開始就能規劃好的,最好能動態調整,這樣就能通過虛擬化技術來做。
    提高硬件使用率的主要思路就是讓一個物理服務器上跑多個程序,程序之間需要一種隔離機制來保證大體上互不影響,這里有個悖論,因為我們的目的是提高資源利用率,那么最好讓應用互相爭搶資源,然而為了穩定性又需要一定程度的資源隔離。
    兩種隔離思路
    一 鳩占鵲巢,接管操作系統
    由于計算機歷史悠久的分層設計思路,可以想到讓程序隔離必然要在操作系統層與應用層之間有一種機制,讓應用認為自己在一個獨立的操作系統中,而操作系統又要支持讓應用互相隔離。那么就要引入一層中間層,這層中間層可以模擬操作系統環境來啟動應用,并把應用對操作系統的API調用翻譯過來傳達給下層實際的操作系統,這就是Xen,KVM的設計思路。
    這樣的做法會比較重,因為相當于將操作系統重新封裝了一遍。至于為什么要翻譯一遍,這是由于虛擬機的操作系統可能是linux的各種方言版本,也有可能是windows,而實際下層提供操作系統服務的宿主系統一般都是同一個linux版本,所以上層虛擬機的各種cpu指令需要通過虛擬層翻譯過來傳給下層實際的操作系統,這里還會涉及到比較復雜的上層是32位系統,下層是64位系統,連指令集都不一樣,這些都會有性能損耗。這就是純軟件模擬的問題, 下圖可以解釋沒有硬件支持的CPU虛擬化時操作系統與程序的關系:
    為了安全,一些特權級指令只允許操作系統發出,普通的應用程序是不允許調用的。但要做到虛擬化,則必然需要將虛擬化軟件作為操作系統的底層,讓其運行在ring0的模式,而把操作系統運行在ring1模式,這明顯會有很多挑戰。
    針對這個問題,Intel后期為支持虛擬化增加了VT-x,為CPU的工作模式增加了VMX root operation和VMX non-root operation兩種模式。當客戶操作系統出現特權指令時提供了機制能退出到根模式,由虛擬機監視器(VMM)來處理。
    二 操作系統支持,隔離進程空間
    Linux認識到了虛擬化的意義,提供了另外一種虛擬化的方式 - LXC(Linux Containers)。 此種思路是操作系統為程序提供虛擬執行空間,可以理解為一種容器,操作系統為要運行在容器中的應用程序提供所需的CPU,內存,網絡等底層資源支持,當然,此種方式還能靈活的更改綁定的CPU個數,并能進行CPU超配,提高資源利用率。
    這種模式所有容器內的進程都共享同一個操作系統內核,所以限制也在這里,容器內的進程需要是個linux程序,windows程序用的windows操作系統API在這里是不存在的。
    這里還要提一下Docker,其實看了前面對于LXC的介紹就知道,Docker的進程隔離思路與LXC是一樣的,所以Docker早期也是基于LXC開發的。Docker的理念與OO設計中的單一職責一樣,容器只支持一個進程,拒絕變成瑞士軍刀。
    關于Docker,此處為占位符,下次看看它的設計。虛擬化技術仍在快速發展,應用程序員在寫代碼時完全不知道另外一批偏硬件,系統開發的程序員做了些什么,各種小小的分工,打造了如今的計算機體系,消費者們也得到了想要的(網絡游戲,打車,外賣,搜索)。


    文章來自微信平臺「麥芽面包」
    微信公眾號「darkjune_think」轉載請注明。
    如果覺得有趣,微信掃一掃關注公眾號。
    (繼續閱讀...)
    文章標籤

    AutoPoster 發表在 痞客邦 留言(0) 人氣(11)

    • 個人分類:生活學習
    ▲top
    • 3月 09 週四 201720:43
    • [翻譯]AKKA筆記 - ACTOR生命周期 - 基本 -5


    文章出處

    原文地址:http://rerun.me/2014/10/21/akka-notes-actor-lifecycle-basic/


    (請注意這了討論的生命周期并不包括 preRestart 或者postRestart方法,當我們討論supervision時候我們會說這個)
    基本的Actor生命周期很直觀。除了一點小不同,你可以直接拿基本Actor生命周期與Java Servlet生命周期作比較。
  • 像其他常規類一樣,我們有一個構造函數。

  • preStart方法會被調用。 這里你可以在postStop初始化一些稍后你想清理的資源。

  • receive方法用作服務或者消息處理,占用了大部分時間。

  • 先看下一個打印了生命周期的簡單actor。
    DUMB LIFECYCLE ACTOR
    package me.rerun.akkanotes.lifecycle
    import akka.actor.{ActorLogging, Actor}
    import akka.event.LoggingReceive
    class BasicLifecycleLoggingActor extends Actor with ActorLogging{
    log.info ("Inside BasicLifecycleLoggingActor Constructor")
    log.info (context.self.toString())
    override def preStart() ={
    log.info("Inside the preStart method of BasicLifecycleLoggingActor")
    }
    def receive = LoggingReceive{
    case "hello" => log.info ("hello")
    }
    override def postStop()={
    log.info ("Inside postStop method of BasicLifecycleLoggingActor")
    }
    }

    APP
    LifecycleApp只初始化,發一個消息給Actor然后關掉ActorSystem.
    import akka.actor.{ActorSystem, Props}
    object LifecycleApp extends App{
    val actorSystem=ActorSystem("LifecycleActorSystem")
    val lifecycleActor=actorSystem.actorOf(Props[BasicLifecycleLoggingActor],"lifecycleActor")
    lifecycleActor!"hello"
    //wait for a couple of seconds before shutdown
    Thread.sleep(2000)
    actorSystem.shutdown()
    }

    輸出
    Inside BasicLifecycleLoggingActor Constructor
    Actor[akka://LifecycleActorSystem/user/lifecycleActor#-2018741361]
    Inside the preStart method of BasicLifecycleLoggingActor
    hello
    Inside postStop method of BasicLifecycleLoggingActor

    那個在基礎Actor生命周期與Servlet生命周期的一點不同是什么?
    Actor生命周期中的構造函數和preStart是沒什么不一樣的。
    我把context.self在構造函數中進行打印的原因就是 - 不像Servlets,Actor在構造函數中可以訪問到ActorContext。而preStart與構造函數間的差別就很微妙了。如果你要打破砂鍋問到底,我們再看下之前說的不同 - 當Actor重啟時(失敗的case)調用preStart是可控的。 用構造函數就不可能了。
    什么時候POSTSTOP會被調用?
    像我們前面看到的程序, postStrop在ActorSystem關閉時會被調用。還有很多其他的機會能調用到這個回調。
    1.ACTORSYSTEM.STOP()
    我們可以用ActorSystem的stop方法來停止一個Actor和ActorContext
    object LifecycleApp extends App{
    val actorSystem=ActorSystem("LifecycleActorSystem")
    val lifecycleActor=actorSystem.actorOf(Props[BasicLifecycleLoggingActor],"lifecycleActor")
    actorSystem.stop(lifecycleActor);
    ...
    ...
    }

    2.ACTORCONTEXT.STOP
    ** 1)可以傳個消息(外部或自己給自己傳)**
    class BasicLifecycleLoggingActor extends Actor with ActorLogging{
    ...
    ...
    def receive = LoggingReceive{
    case "hello" => log.info ("hello")
    case "stop" => context.stop(self)
    }

    和
    object LifecycleApp extends App{
    val actorSystem=ActorSystem("LifecycleActorSystem")
    val lifecycleActor=actorSystem.actorOf(Props[BasicLifecycleLoggingActor],"lifecycleActor")
    lifecycleActor!"stop"
    ...
    ...

    ** 2)或無原因的把自己殺掉(這只是為了好玩。沒有一個有追求的Actor會這么做)
    class BasicLifecycleLoggingActor extends Actor with ActorLogging{
    log.info ("Inside BasicLifecycleLoggingActor Constructor")
    log.info (context.self.toString())
    context.stop(self)
    ...
    ...

    3.毒藥
    在之前的例子,我們從LifecycleApp給Actor傳了一個叫stop的消息。Actor在收到消息后用context.stop把自己殺掉。我們也可以通過傳遞一個毒藥(PoisonPill)消息到目標actor來達到同樣的目的。請記住這個毒藥消息,會像前面的stop消息一樣被放在常規mailbox中,當被處理到的時候才會運行。
    object LifecycleApp extends App{
    val actorSystem=ActorSystem("LifecycleActorSystem")
    val lifecycleActor=actorSystem.actorOf(Props[BasicLifecycleLoggingActor],"lifecycleActor")
    lifecycleActor!PoisonPill
    ...
    ...

    4.KILL
    除了發送一個毒藥(PoisonPill), 你也可以給目標Actor發送一個kill消息。
    lifecycleActor ! Kill
    發送毒藥消息和kill消息,區別很微妙但很重要。
  • 用PoisonPill,一個Terminated消息會被發送到所有的watcher(稍后我們會在DeathWatch章節中看到)

  • 發送kill消息,宿主Actor會拋出一個ActorKilledException并被發送給Supervisor(稍后我們會在Supervision章節中看到)



  • 細枝末節
    我前面說的常規mailbox是啥意思?是否還有個“特別”mailbox?是的,確實有!我們會在討論supervision和system消息時說到這個。


    TERMINATION
    當Actor停止時,他會進入一個Terminated狀態。你馬上就會想到一個問題,那些發到一個已經是terminated狀態的Actor的消息會怎么樣?
    讓我們看看:
    APP
    object LifecycleApp extends App{
    val actorSystem=ActorSystem("LifecycleActorSystem")
    val lifecycleActor=actorSystem.actorOf(Props[BasicLifecycleLoggingActor],"lifecycleActor")
    lifecycleActor!"hello"
    lifecycleActor!"stop"
    lifecycleActor!"hello" //Sending message to an Actor which is already stopped
    }

    ACTOR - 與之前一樣
    class BasicLifecycleLoggingActor extends Actor with ActorLogging{
    def receive = LoggingReceive{
    case "hello" => log.info ("hello")
    case "stop" => context.stop(self)
    }
    }

    輸出
    BasicLifecycleLoggingActor - hello
    akka.actor.RepointableActorRef - Message [java.lang.String] from Actor[akka://LifecycleActorSystem/deadLetters] to Actor[akka://LifecycleActorSystem/user/lifecycleActor#-569230546] was not delivered. [1] dead letters encountered. This logging can be turned off or adjusted with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letters-during-shutdown'.

    從日志中可以看到,這里對deadletters有一些引用。任何你發給那個已經terminated的Actor的消息都會轉發給一個叫DeadLetterActor的內部Actor的mailbox。


    那么這之后又發生了什么?
    DeadLetter Actor處理它mailbox里的消息,把每個消息都封裝成一個DeadLetter并且把它發布到EventStream中。
    另一個叫DeadLetterListener的Actor消費所有的DeadLetter并把它輸出成日志消息。從這里看。
    記住,當我們說日志的時候,我們可以看到所有輸出到EventStream的消息并且可以隨意消費 - 只是這個消費者一樣必須是個Actor。讓我們試試。
    在我們的例子中,我們消費EventStream并且觀看所有DeadLetter消息最后打印到console(這沒有創造力??)當然,我們還能自由的做任何事如生成告警,把它保存到數據庫或把它拿去作分析。
    訂閱EVENTSTREAM的DEADLETTERS
    import akka.actor.ActorSystem
    import akka.actor.Props
    import akka.actor.PoisonPill
    import akka.actor.DeadLetter
    import akka.actor.Actor
    object LifecycleApp extends App {
    val actorSystem = ActorSystem("LifecycleActorSystem")
    val lifecycleActor = actorSystem.actorOf(Props[BasicLifecycleLoggingActor], "lifecycleActor")
    val deadLetterListener = actorSystem.actorOf(Props[MyCustomDeadLetterListener])
    actorSystem.eventStream.subscribe(deadLetterListener, classOf[DeadLetter])
    lifecycleActor ! "hello"
    lifecycleActor ! "stop"
    lifecycleActor ! "hello"
    }
    class MyCustomDeadLetterListener extends Actor {
    def receive = {
    case deadLetter: DeadLetter => println(s"FROM CUSTOM LISTENER $deadLetter")
    }
    }

    輸出
    164 [LifecycleActorSystem-akka.actor.default-dispatcher-4] INFO BasicLifecycleLoggingActor - hello
    167 [LifecycleActorSystem-akka.actor.default-dispatcher-4] INFO akka.actor.RepointableActorRef - Message [java.lang.String] from Actor[akka://LifecycleActorSystem/deadLetters] to Actor[akka://LifecycleActorSystem/user/lifecycleActor#-782937925] was not delivered. [1] dead letters encountered. This logging can be turned off or adjusted with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letters-during-shutdown'.
    FROM CUSTOM LISTENER DeadLetter(hello,Actor[akka://LifecycleActorSystem/deadLetters],Actor[akka://LifecycleActorSystem/user/lifecycleActor#-782937925])



    文章來自微信平臺「麥芽面包」(微信掃描二維碼關注)。未經允許,禁止轉載。
    (繼續閱讀...)
    文章標籤

    AutoPoster 發表在 痞客邦 留言(0) 人氣(16)

    • 個人分類:生活學習
    ▲top
    • 3月 09 週四 201720:43
    • win8 2502 2503 錯誤


    文章出處
    該錯誤主要是由于權限不足導致的。個人遇到這個問題是安裝mysql的時候遇到的。
    解決辦法:
      1.運行CMD(管理員)
      2.輸入以下命令: msiexec /package "你的安裝文件路徑"
    (繼續閱讀...)
    文章標籤

    AutoPoster 發表在 痞客邦 留言(0) 人氣(8)

    • 個人分類:生活學習
    ▲top
    • 3月 09 週四 201720:43
    • Windows Phone 判斷方向


    文章出處
     public static class Utilities
    {
    public static bool IsInLandscape(this PhoneApplicationPage page)
    {
    return !page.IsInPortrait();
    }
    public static bool IsInPortrait(this PhoneApplicationPage page)
    {
    return page.IsInOrientation(PageOrientation.Portrait |
    PageOrientation.PortraitUp
    | PageOrientation.PortraitDown);
    }
    public static bool IsInOrientation(this PhoneApplicationPage page, PageOrientation testOrientation)
    {
    var orientation = page.Orientation;
    return orientation.IsOrientation(testOrientation);
    }
    public static bool IsOrientation(this PageOrientation orientation, PageOrientation testOrientation)
    {
    return (orientation & testOrientation) > 0;
    }
    }

     
    (繼續閱讀...)
    文章標籤

    AutoPoster 發表在 痞客邦 留言(0) 人氣(4)

    • 個人分類:生活學習
    ▲top
    • 3月 09 週四 201720:43
    • Python入門指南


    文章出處
     
    一.Windows7下的Python環境搭建
    1.Google下載python-2.6.msi安裝包,以管理員身份運行,安裝時候注意不要在有中文目錄的程序下安裝。安裝完成之后可以在開始菜單中看到。
    2.配置環境變量。不用配置也可以,不過配置之后后面會方便很多。
    配置方法:右鍵“我的電腦”選擇“屬性”,切換到“高級”選項卡,選擇環境變量,在“系統變量”下選擇“Path”變量,然后點擊“編輯”按鈕,添加Python安裝目錄。配置完成之后可以打開cmd輸入”python”進行測試。如果出現下圖所示,則表示配置成功。此步驟熟悉Java的同學應該比較熟悉。     
     
    二.Python基礎語法
      
    關于Python 的基礎教程網上有很多,我的看的電子書。 推薦《Python核心編程(第二版)》,大家可以去電驢下載電子版。Python是弱類型語言,對Javascript比較熟悉同學學起來應該會快一點。有人說Python不需要學習,不過我認為一些基本的API的使用還是要記得的。
      這里給出一個地址:http://www.verycd.com/topics/2765155/
     
    三.Python 開發環境
      
    如果覺得Python自帶的IDE用著很不爽的下,有下面3個自認為比較好的第三方開發環境。
    如果你是.NET開發人員用的是Visual Studio 2010或者更高版本的話,那么你可以http://pytools.codeplex.com/ 下載Python Tools for Visual Studio,然后進行安裝即          可。  
    如果你是Java開發人員用的是Eclipse的話,那么你可以參考http://www.rose-hulman.edu/class/csse/resources/Eclipse/eclipse-python-configuration.htm 這里進行Eclipse環境的搭建。
    如果你想開發GUI程序的話,那么你可以Google下載boa-constructor-0.6.1.src.win32.exe 和 wxPython2.8-win32-unicode-2.8.12.1-py26.exe 這兩個拓展包,前者為GUI拓展包,后者對前者提供了界面操作的支持。
      如果你想開發能在沒有Python環境上運行Windows GUI程序,那么你需要以下工具。
      Python打包工具。Python打包工具有很多種,常用的有Pyinstaller,py2exe等,具體可以Google。后面具體介紹Py2exe的使用。
      Python擴展包。Python有非常多的開源擴展包以及強大的擴展能力,一般網絡編程,WEB編程,客戶端編程 等 你都可以在網上找到非常豐富的資源。下面給出了一些:
      http://www.itlong.com/thread-1685-1-1.html
     
    下一節介紹boa-constructor的使用和Python打包工具的使用以及如何使用第三方擴展庫。
    (繼續閱讀...)
    文章標籤

    AutoPoster 發表在 痞客邦 留言(0) 人氣(34)

    • 個人分類:生活學習
    ▲top
    • 3月 09 週四 201720:43
    • Python Boa-constructor的使用


    文章出處
      上篇介紹了Python的環境搭建,主要是開發環境的介紹,本篇主要介紹Python的GUI開發工具Boa-constructor的使用和我們的程序開發完畢后的打包問題,本篇還會介紹在Python中我們如何使用第三方擴展庫。
     
    一、如何選擇GUI開發工具
    Python的gui開發工具有很多,有Thiner,WxPython,PyQt,pyGtk,Jython,MFC,IronPython,PythonCard,Dabo,AnyGui,Wpy等,簡直有太多了,選幾種用的比較多的簡單介紹一下,目前我用的是WxPyton。
    Tkinter
    Tkinter 似乎是與tcl語言同時發展起來的一種界面庫。tkinter是python的配備的標準gui庫,也是opensource的產物。Tkinter可用 于windows/linux/unix/macintosh操作系統,而且顯示風格是本地化的。Tkinter用起來非常簡單,python自帶的 IDLE就是采用它寫的。除此外,tkinter的擴展集pmw和Tix功能上都要相對它強大,但tkinter卻是最基本的。我認為,在用python 做gui開發,tkinter是最基本的知識,所以這個環節是必須要學習的。你或許在以后的開發中并不常用tkinter,但是一些小型的應用上面,他還 是很有用的,而且開發速度也很快。
    WxPython
    WxWidgets應該算是近幾年了比較流行的GUI跨平臺開發技術了。 wxWidgets有不同的版本應用,有c++的,也有basic的,現在在python上面也有較好的移植。wxpython的功能上面要強于 tkinter,她提供了超過200個類,面向對象的編程風格,設計的框架類似于MFC。對于大型GUI應用上面,wxPython還是具有很強的優勢 的。boa constructor可以幫助我們快速可視地構建wxwidgets界面。
    Jython
    嘗試過用python訪問java類庫嗎,那么就用jython吧。jython其實可以認為是另外一個python開發環境,基于java的,但是大多數 的CPython調用jython下還是可以的。你可以在jython環境下像使用java一樣來通過python的語法來調用java語言,真的很酷。
    MFC
    Windows Pywin32允許你像VC一樣的形式來使用PYTHON開發win32應用。代碼風格可以類似win32 sdk,也可以類似MFC,由你選擇。如果你仍不放棄vc一樣的代碼過程在python下,那么這就是一個不錯的選擇。
    WPY
    MFC風格的Gui開發庫,代碼風格也類似于MFC,僅管如此,你依舊可以使用這個庫來開發GUI應用,而不用擔心平臺移植的問題。
    IronPython
    如果你要想開發.net下面的應用的話,那么IronPython就是你的選擇,與jython有點類似,他同樣支持標準的python模塊,但同樣增加了 對.net庫的支持。你也可以理解為他是另一個python開發環境。你可以非常方便地使用python語法進行.net應用的開發,這一點聽起來真的挺 有意思。
      上面的內容是Google找的,總之,介紹了這么多,我個人意見是,如果你是java用戶,你可以選擇用jython;如果你是.net用戶,那么就用ironPython吧。如果你對Visual C++很熟悉,那么你可以使用MFC,WPY或是wxPython,當然我更建議wxPython了。當然,我認為對于tkinter是每一個原來搞C的 人都應該了解和學習的GUI庫,因為她很輕便,小型應用就可以使用她來搞定,而對于較大型應用可以采用pyGtk,pyQt,WxPython或 PythonCard來搞定,這樣的話,既可以注重知識的銜接性,也可以快速進行開發了。
     
    二、Python擴展庫
      如果說強大的標準庫奠定了python發展的基石,豐富的第三方庫則是python不斷發展的保證,隨著python的發展一些穩定的第三庫被加入到了標準庫里面,可以在http://pypi.python.org/pypi?%3Aaction=index找到非常多的Python擴展庫,其中下面講的wxPython就是其中之一。我猜你喜歡Python的其中一個理由一定是它的非常多的拓展庫,下面列出了常用的Python第三方庫。
    Django    開源web開發框架,它鼓勵快速開發,并遵循MVC設計,我以前用過很多次,比較好用,開發周期短。
    ActiveGrid  企業級的Web2.0解決方案。
    Karrigell     簡單的Web框架,自身包含了Web服務,py腳本引擎和純python的數據庫PyDBLite 。
    webpy    一個小巧靈活的Web框架,雖然簡單但是功能強大 。
    CherryPy    基于Python的Web應用程序開發框架 。
    Pylons    基于Python的一個極其高效和可靠的Web開發框架 。
    Zope     開源的Web應用服務器。
    TurboGears   基于Python的MVC風格的Web應用程序框架。
    Twisted     流行的網絡編程庫,大型Web框架。
    Quixote     Web開發框架。
    Matplotlib  用Python實現的類matlab的第三方庫,用以繪制一些高質量的數學二維圖形 。
    SciPy     基于Python的matlab實現,旨在實現matlab的所有功能 。
    NumPy     基于Python的科學計算第三方庫,提供了矩陣,線性代數,傅立葉變換等等的解決方案 。
    PyGtk      基于Python的GUI程序開發GTK+庫。
    PyQt     用于Python的QT開發庫。
    WxPython     Python下的GUI編程框架,與MFC的架構相似。
    Tkinter      Python下標準的界面編程包。
    BeautifulSoup 基于Python的HTML/XML解析器,簡單易用。
    PIL        基于Python的圖像處理庫,功能強大,對圖形文件的格式支持廣泛。
    MySQLdb      用于連接MySQL數據庫。
    cElementTree高性能XML解析庫,Py2.5應該已經包含了該模塊,因此不算一個第三方庫了。
    PyGame       基于Python的多媒體開發和游戲軟件開發模塊。
    Py2exe     將python腳本轉換為windows上可以獨立運行的可執行程序。
    pefile       Windows PE文件解析器
     
    三、boa-constructor的使用
    我是一個.Net開發人員,我之所以不選擇IronPython的原因是不想再讓客戶端去安裝.net framework這么龐大的庫,所以我選擇了wxPython。wxPython的介紹上面有,我個人覺得wxPython還是比較容易學習的。因為有API可以供我們查閱,它和MFC有很多相同或者相似的地方,我個人還是比較喜歡,或者可以我沒有去嘗試其他的庫吧,因為我發現我已經喜歡上它了。
    和wxPython庫搭配的開發IDE 也有很多,spe, boa-constructor,eclipse+pydev. 個人建議選擇boa-constructor 和 Eclipse+Pydev 搭配。其中boa-constructor用來開發界面,Eclipse+Pydev 用來編寫代碼。
    boa-constructor個人感覺還是非常不錯的,剛開始可能會不懂,比較吃力一點,但是等你學會使用了以后相信你會喜歡上它的。下載地址:點擊此處下載。  安裝boa-constructor之前請確定你的機器上已經安裝了wxPython 和Python。目前需要wxPython 2.4.0.7 or higher and Python 2.1 or higher.
    boa-constructor 安裝完畢后桌面或者開始菜單并沒有它的啟動快捷方式或者是目錄。你需要在你的Python安裝目錄下找到Python26\Lib\site-packages\boa-constructor 這個路徑下Boa.py文件。Boa.py為boa-constructor啟動文件。
    1.雙擊Boa.py文件加載完畢后會出現如下界面。
                         

    1. 其中1中的最上方一個窗口為boa-constructor的工具條,里面有基本的一些控件等。見下圖:


     
    其中Python,wxPython, boa-constructor 的幫助文檔你也會在這個工具條中找到,這幾個文檔能為你后面的開發工作起到很大的作用。
  • 下面的為檢視器窗口,它的主要作用相當于VS中的屬性窗口,包括一些控件的屬性,事件等。

  •  
  • 主工作區域窗口就不進行介紹了,都是中文顯示。如下圖:

  •  
     
     
    下面簡單介紹一下如何新建工程。
     
  • 點擊最上方工具條視圖中的第五個圖標。

  •  
     
  • 點擊之后,主編輯器窗口會出來2個未保存的新建文件(*App1*,*Frame1*),其中App1為程序的啟動文件,里面包含應用程序初始化的一些信息以及Main函數,Frame1為生成的一個新頁面,接下面我們需要做的就是繪制界面了。

  •  
     
  • 切換到Frame1選項卡,然后按快捷鍵F12或者點擊框架設計器按鈕(),此時會彈出Frame1的設計界面,如下圖:

  •  
     
  • 從工具條拖拉我們需要的控件到設計器區域,我拖拽了一個Button和一個Label,另外我修改了程序的標題。如下圖:

  •  
     
  • WxPython也是采用的事件驅動的模型,在左邊的檢視器窗口我們可以看到某一個控件的信息等,包括該控件的基本屬性信息,以及構造該空間所需的必須屬性和可設置屬性,另外還有就是該控件所擁有的事件,如下圖:

  •  
     
  • 如何在wxPython中添加事件?其實很簡單,打開檢視器窗口,切換到Evts選項卡,左邊菜單欄會列出該控件所具有的事件,然后右邊雙擊就可以了,最后,別忘了對你的更改進行提交(上面對號),如下圖:

  •  
     
  • 下面為Boa為我們生成的界面代碼,我們的后臺邏輯代碼可以在Eclipse中利用其更好的代碼提示為我們提供便利。

  • View Code

     1 # -*- coding: gb2312 -*-
    2
    3 #Boa:Frame:Frame1
    4
    5
    6
    7 import wx
    8
    9
    10
    11 def create(parent):
    12
    13 return Frame1(parent)
    14
    15
    16
    17 [wxID_FRAME1, wxID_FRAME1BUTTON1, wxID_FRAME1LABEL1,
    18
    19 ] = [wx.NewId() for _init_ctrls in range(3)]
    20
    21
    22
    23 class Frame1(wx.Frame):
    24
    25 def _init_ctrls(self, prnt):
    26
    27 # generated method, don't edit
    28
    29 wx.Frame.__init__(self, id=wxID_FRAME1, name='', parent=prnt,
    30
    31 pos=wx.Point(426, 280), size=wx.Size(400, 250),
    32
    33 style=wx.DEFAULT_FRAME_STYLE,
    34
    35 title=u'\u6211\u7684\u7b2c\u4e00\u4e2aWxPython\u7a0b\u5e8f')
    36
    37 self.SetClientSize(wx.Size(384, 212))
    38
    39
    40
    41 self.Label1 = wx.StaticText(id=wxID_FRAME1LABEL1,
    42
    43 label=u'\u6211\u559c\u6b22BOA', name=u'Label1', parent=self,
    44
    45 pos=wx.Point(64, 24), size=wx.Size(97, 25), style=0)
    46
    47 self.Label1.SetBackgroundColour(wx.Colour(228, 252, 230))
    48
    49 self.Label1.SetFont(wx.Font(14, wx.SWISS, wx.NORMAL, wx.NORMAL, False,
    50
    51 u'\u5fae\u8f6f\u96c5\u9ed1'))
    52
    53
    54
    55 self.button1 = wx.Button(id=wxID_FRAME1BUTTON1,
    56
    57 label=u'\u70b9\u51fb\u6309\u94ae', name='button1', parent=self,
    58
    59 pos=wx.Point(192, 24), size=wx.Size(75, 24), style=0)
    60
    61 self.button1.Bind(wx.EVT_BUTTON, self.OnButton1Button,
    62
    63 id=wxID_FRAME1BUTTON1)
    64
    65
    66
    67 def __init__(self, parent):
    68
    69 self._init_ctrls(parent)
    70
    71
    72
    73 def OnButton1Button(self, event):
    74
    75
    76
    77 fileDlg = wx.FileDialog(self,u'FileDialog',u'choose file')
    78
    79 re = fileDlg.ShowModal()
    80
    81 if re==5100:
    82
    83 sr= fileDlg.GetFilename()
    84
    85 print sr
    86
    87 self.ShowDlg(sr)
    88
    89 #todo:
    90
    91 event.Skip()
    92
    93
    94
    95 def ShowDlg(self,content=""):
    96
    97 dlg = wx.MessageDialog(self,content,
    98
    99 '確認框',
    100
    101 wx.OK | wx.ICON_INFORMATION
    102
    103 )
    104
    105 dlg.ShowModal()


     
     
    至此,BOA的使用簡單介紹到這里,后面更多的探索還要自己去慢慢摸索。
     
    (繼續閱讀...)
    文章標籤

    AutoPoster 發表在 痞客邦 留言(0) 人氣(196)

    • 個人分類:生活學習
    ▲top
    • 3月 09 週四 201720:43
    • 并行編程(PLINQ)學習筆記

    文章出處

      在多核CPU在今天和不久的將來,計算機將擁有更多的內核,Microsoft為了利用這個硬件特性,于是在Visual Studio 2010 和 .NET Framework 4的發布及以上版本中,添加了并行編程這個新特性,我想它以后勢必會改變我們的開發方式。


      在以前或者說現在,我們在并行開發的時候可能會想到利用多線程和鎖技術來做,充分利用多CPU的特性,但是當我們了解并掌握了并行編程技術之后,我們可以不必擔心在多線程中的資源死鎖和繁瑣的DEBUG查找等低級操作。新的并行編程簡單了并行開發,使我們可以用新的方法來編程并行運算的代碼,從而不必直接去處理線程或者線程池。下圖從較高層面上概述了 .NET Framework 4 中的并行編程體系結構。


     


      園子里已經有很多關于LINQ的博客(如一線碼農的《8天玩轉并行開發》系列,非常感謝這些分享的人。:)),本來是不想再寫的,但是想了一下還是寫一下吧,算是作為自己的學習筆記了。


      下面為并行編程所用到的數據,摘自MSDN。
















































    技術



    說明



    任務并行庫 (TPL)



    提供針對 System.Threading.Tasks.Parallel 類的文檔(包括 For 和 ForEach 循環的并行版本),還提供了針對 System.Threading.Tasks.Task 類的文檔(描繪了表示異步操作的首選方式)。



    并行 LINQ (PLINQ)



    LINQ to Objects 的并行實現,該實現顯著提高了許多情況下的性能。



    用于并行編程的數據結構



    提供一些鏈接,這些鏈接指向有關線程安全集合類、輕量同步類型以及延遲初始化類型的文檔。



    并行診斷工具



    提供一些鏈接,這些鏈接指向有關 Visual Studio 任務和并行堆棧調試器窗口以及并發可視化工具的文檔,其中包含 Visual Studio Application Lifecycle Management 探查器中的一組視圖,您可以使用這些視圖來調試和調整并行代碼的性能。



    PLINQ 和 TPL 的自定義分區程序



    描述分區程序的工作方式,以及如何配置默認分區程序或創建新的分區程序。



    任務工廠



    描述 System.Threading.Tasks.TaskFactory 類的作用。



    任務計劃程序



    描述計劃程序的工作方式,以及如何配置默認計劃程序。



    在 PLINQ 和 TPL 中的 Lambda 表達式



    簡要概述 C# 和 Visual Basic 中的 lambda 表達式,并演示如何在 PLINQ 和任務并行庫中使用這些表達式。



    其他閱讀材料(并行編程)



    提供一些鏈接,這些鏈接指向其他文檔以及在 .NET Framework 中進行并行編程的示例資源。



    .NET Framework 高級讀物



    高級主題(例如線程處理和并行編程)的頂級節點。




     


    .Net framework并行編程相關為我們提供了一個新的命名空間:System.Threading.Tasks。







































































     類說明
    公共類Parallel提供對并行循環和區域的支持。
    公共類ParallelLoopState可用來使 Parallel 循環的迭代與其他迭代交互。此類的實例由 Parallel 類提供給每個循環;不能在您的用戶代碼中創建實例。
    公共類ParallelOptions存儲用于配置 Parallel 類的方法的操作的選項。
    公共類Task表示一個異步操作。
    公共類Task<TResult>表示一個可以返回值的異步操作。
    公共類TaskCanceledException表示一個用于告知任務取消的異常。
    公共類TaskCompletionSource<TResult>表示未綁定到委托的 Task<TResult> 的制造者方,并通過 Task 屬性提供對使用者方的訪問。
    公共類TaskExtensions提供一組用于處理特定類型的 Task 實例的靜態方法(在 Visual Basic 中為共享方法)。
    公共類TaskFactory提供對創建和計劃 Task 對象的支持。
    公共類TaskFactory<TResult>提供對創建和計劃 Task<TResult> 對象的支持。
    公共類TaskScheduler表示一個處理將任務排隊到線程中的低級工作的對象。
    公共類TaskSchedulerException表示一個用于告知由 TaskScheduler 計劃的某個操作無效的異常。
    公共類UnobservedTaskExceptionEventArgs為在出錯的 Task 的異常未觀察到時引發的事件提供數據。

     


    首先介紹一下并行編程為我們提供的拓展方法


    System.Linq.ParallelEnumerable 類為LINQ所能查詢的集合IEnumerable提供了拓展方法,讓我們更加容易的使用并行查詢。如下:



    static void Main(string[] args)
    {
    Random random
    = new Random();
    List
    <int> intList = new List<int>();
    for (int i = 0; i < 100; i++)
    {
    intList.Add(random.Next(
    100));
    }
    //查詢大于50的數
    var queryResult = from varable in intList.AsParallel()
    where varable > 50
    select varable;
    queryResult.ForAll
    <int>(tmp => Console.WriteLine(tmp));
    }


    默認PLINQ使用主機上的所有處理器,若要指定并行處理的最大任務數,可以用拓展方法WithDegreeOfParallelism(int degreeOfParallelism),其中degreeOfParallelism為設置的最大任務數量。degreeOfParallelism默認為CPU的核心數,如果CPU多余64核,而沒有手動指定,則為64。


      有必要提一下上面用到的ForAll運算符,在普通的LINQ查詢中,執行被延遲到Foreach循環中,或通過調用方法ToList(),ToArray()等。在 PLINQ 中,還可以使用 foreach 執行查詢和循環訪問結果。但是,foreach 本身不會并行運行,因此,它需要將所有并行任務的輸出合并回到該循環正在其上運行的線程中。在 PLINQ 中,當必須保留查詢結果的最終排序時,以順序方式處理結果時,以及例如當為每個語句調用 Console.WriteLine 時,必須使用 foreach。為了使不需要保留排序時以及結果的處理可自己并行化時更快地執行查詢,請使用 ForAll<TSource> 方法來執行 PLINQ 查詢。ForAll<TSource> 不執行此最終合并步驟。


     


    PLINQ為我們的查詢進行了加速,在編寫PLINQ查詢需要注意的事項。影響PLINQ查詢的因素有下面這些:


      


    1.總體工作的計算開銷。


    為了實現加速,PLINQ 查詢必須具有足夠的適合并行工作來彌補開銷。工作可表示為每個委托的計算開銷與源集合中元素數量的乘積。假定某個操作可并行化,則它的計算開銷越高,加速的可能性就越大。例如,如果某個函數執行花費的時間為 1 毫秒,則針對 1000 個元素進行的順序查詢將花費 1 秒來執行該操作,而在四核計算機上進行的并行查詢可能只花費 250 毫秒。這樣就產生了 750 毫秒的加速。如果該函數對于每個元素需要花費 1 秒來執行,則加速將為 750 秒。如果委托的開銷很大,則對于源集合中的很少幾個項,PLINQ 可能會提供明顯的加速。相反,包含無關緊要委托的小型源集合通常不適合于 PLINQ。


     


    在下面的示例中,queryA 可能適合于 PLINQ(假定其 Select 函數涉及大量工作)。queryB 可能不適合,原因是 Select 語句中沒有足夠的工作,并且并行化的開銷將抵銷大部分或全部加速。



    var queryA = from num in numberList.AsParallel()
    select ExpensiveFunction(num); //good for PLINQ
    var queryB = from num in numberList.AsParallel()
    where num % 2 > 0
    select num; //not as good for PLINQ


    總而言之,就是當我們的Select函數有很少的時候,就不要用PLINQ查詢了。


    2.系統上的邏輯內核數(并行度)。


    適合并行的查詢在具有更多內核的計算機上運行更快,原因是可以在更多并行線程之間分擔工作。加速的總量取決于查詢的總體工作中可并行化的百分比。但是,請不要假定所有查詢在八核計算機上的運行速度都比在四核計算機的運行速度快兩倍。在調整查詢以實現最佳性能時,衡量具有多個內核的計算機上的實際結果十分重要。這一點與第一點相關:更大的數據集需要消耗更多的計算資源。


     


    3.操作的數量和種類。


    對于必須要保持元素在源序列中的順序的情況,PLINQ 提供了 AsOrdered 運算符。排序會產生開銷,但此開銷通常是適度的。GroupBy 和 Join 操作同樣也會產生開銷。如果允許按任意順序處理源集合中的元素,并在這些元素就緒時立即將它們傳遞到下一個運算符,則 PLINQ 的性能最佳。


     


    4.查詢的執行形式。


    如果要通過調用 ToArray 或 ToList 存儲查詢的結果,則必須將來自所有并行線程的結果合并為單個數據結構。這會涉及到不可避免的計算開銷。同樣,如果您使用 foreach循環對結果進行迭代,則需要將來自工作線程的結果序列化到枚舉器線程上。但是,如果只需要基于來自每個線程的結果執行某個操作,您可以使用 ForAll 方法在多個線程上執行此工作。


     


    5.合并選項的類型。


    可將 PLINQ 配置為將其輸出放入緩沖區,并以區塊方式或在整個結果集完成后同時生成輸出,或者在個別結果生成時流式傳送這些結果。前者可縮短總體執行時間,而后者可縮短生成的元素之間的延遲。盡管合并選項并不總是對總體查詢性能有很大影響,但是,由于它們控制用戶必須等待多長時間才能看到結果,因此可能會對感覺到的性能產生影響。


     


    6.分區的種類。


    在某些情況下,針對可建立索引的源集合進行的 PLINQ 查詢可能會產生不平衡的工作負載。如果發生這種情況,您也許能夠通過創建自定義分區程序來提高查詢性能。


     


    下一節,將寫一下PLINQ中的分區和自定義分區。


    (繼續閱讀...)
    文章標籤

    AutoPoster 發表在 痞客邦 留言(0) 人氣(112)

    • 個人分類:生活學習
    ▲top
    • 3月 09 週四 201720:43
    • PLINQ中的分區


    文章出處

      最近因為比較忙,好久沒有寫博客了,這篇主要給大家分享一下PLINQ中的分區。上一篇介紹了并行編程,這邊詳細介紹一下并行編程中的分區和自定義分區。


      先做個假設,假設我們有一個200Mb的文本文件需要讀取,怎么樣才能做到最優的速度呢?對,很顯然就是拆分,把文本文件拆分成很多個小文件,充分利用我們計算機中的多核cpu的優勢,讓每個cpu都充分的利用,達到效率的最大化。然而在PLINQ中也是,我們有一個數據源,如果想進行最大的并行化操作,那么就需要把其拆分為可以多個線程同時訪問的多個部分,這就是PLINQ中的分區。當然,微軟已經為我們想到了這一點,知道他的用戶可能會有這個需求,所以就先說一下微軟給我們提供的默認的一個分區程序吧。


      微軟提供的默認的分區程序又叫做任務并行庫(TPL),其實就是當你用PLINQ的ForEach的時候,默認在其內部就會給我們進行分區。怎么樣,是不是很方便。不過有時候,你可能會需要自己來進行拆分,那么就是另外一種跟高級一點的用法了,就是PLINQ的自定義分區。自定義分區有兩種,一種是按照范圍分區,另一種是按照區塊分區。其中按照范圍分區在針對鏈表集合能夠提供非常好的性能,比如IList等,不過它也有一點缺點那就是如果一個線程提前完成,它將無法幫助其他線程完成它們的工作。按照區塊分區是當我們不知道我們所要操作的集合的大小的時候,可以使用按照區塊分區,在按區塊分區中,并行循環或查詢中的每個線程或任務都使用一個區塊中一定數量的源元素,對它們進行處理,然后返回檢索其他元素。分區程序可確保分發所有元素,并且沒有重復項。區塊可為任意大小。


      通常,只有當委托的執行時間為較短到中等程度,源具有大量的元素,并且每個分區的總工作量大致相等時,按范圍分區的速度才會較快。因此,按區塊分區的速度在大多數情況下較快。對于元素數量很少或委托執行時間較長的源,則按區塊分區和按范圍分區的性能大致相等。


      那么我們如何實現動態分區呢?下面有一個摘自MSDN的示例。


      每次分區對枚舉器調用 MoveNext 時,枚舉器都會提供包含一個列表元素的分區。對于 PLINQ 和 ForEach,分區是一個 Task 實例。由于請求同時在多個線程上發生,因此對當前索引的訪問是同步的。


     



     1 //
    2 // An orderable dynamic partitioner for lists
    3 //
    4 class OrderableListPartitioner<TSource> : OrderablePartitioner<TSource>
    5 {
    6 private readonly IList<TSource> m_input;
    7
    8 public OrderableListPartitioner(IList<TSource> input)
    9 : base(true, false, true)
    10 {
    11 m_input = input;
    12 }
    13
    14 // Must override to return true.
    15 public override bool SupportsDynamicPartitions
    16 {
    17 get
    18 {
    19 return true;
    20 }
    21 }
    22
    23 public override IList<IEnumerator<KeyValuePair<long, TSource>>>
    24 GetOrderablePartitions(int partitionCount)
    25 {
    26 var dynamicPartitions = GetOrderableDynamicPartitions();
    27 var partitions =
    28 new IEnumerator<KeyValuePair<long, TSource>>[partitionCount];
    29
    30 for (int i = 0; i < partitionCount; i++)
    31 {
    32 partitions[i] = dynamicPartitions.GetEnumerator();
    33 }
    34 return partitions;
    35 }
    36
    37 public override IEnumerable<KeyValuePair<long, TSource>>
    38 GetOrderableDynamicPartitions()
    39 {
    40 return new ListDynamicPartitions(m_input);
    41 }
    42
    43 private class ListDynamicPartitions
    44 : IEnumerable<KeyValuePair<long, TSource>>
    45 {
    46 private IList<TSource> m_input;
    47 private int m_pos = 0;
    48
    49 internal ListDynamicPartitions(IList<TSource> input)
    50 {
    51 m_input = input;
    52 }
    53
    54 public IEnumerator<KeyValuePair<long, TSource>> GetEnumerator()
    55 {
    56 while (true)
    57 {
    58 // Each task gets the next item in the list. The index is
    59 // incremented in a thread-safe manner to avoid races.
    60 int elemIndex = Interlocked.Increment(ref m_pos) - 1;
    61
    62 if (elemIndex >= m_input.Count)
    63 {
    64 yield break;
    65 }
    66
    67 yield return new KeyValuePair<long, TSource>(
    68 elemIndex, m_input[elemIndex]);
    69 }
    70 }
    71
    72 IEnumerator IEnumerable.GetEnumerator()
    73 {
    74 return
    75 ((IEnumerable<KeyValuePair<long, TSource>>)this)
    76 .GetEnumerator();
    77 }
    78 }
    79 }
    80
    81 class ConsumerClass
    82 {
    83 static void Main()
    84 {
    85 var nums = Enumerable.Range(0, 10000).ToArray();
    86 OrderableListPartitioner<int> partitioner = new OrderableListPartitioner<int>(nums);
    87
    88 // Use with Parallel.ForEach
    89 Parallel.ForEach(partitioner, (i) => Console.WriteLine(i));
    90
    91
    92 // Use with PLINQ
    93 var query = from num in partitioner.AsParallel()
    94 where num % 2 == 0
    95 select num;
    96
    97 foreach (var v in query)
    98 Console.WriteLine(v);
    99 }
    100 }


      這是按區塊分區的示例,其中每個區塊都由一個元素組成。通過一次提供多個元素,您可以減少鎖爭用,并在理論上實現更快的性能。但是,有時較大的區塊可能需要額外的負載平衡邏輯才能使所有線程在工作完成之前保持忙碌。


    (繼續閱讀...)
    文章標籤

    AutoPoster 發表在 痞客邦 留言(0) 人氣(22)

    • 個人分類:生活學習
    ▲top
    • 3月 09 週四 201720:42
    • SQL語句優化(轉載)


    文章出處
    一、操作符優化
    1、IN 操作符
    用IN寫出來的SQL的優點是比較容易寫及清晰易懂,這比較適合現代軟件開發的風格。但是用IN的SQL性能總是比較低的,從Oracle執行的步驟來分析用IN的SQL與不用IN的SQL有以下區別:
    ORACLE試圖將其轉換成多個表的連接,如果轉換不成功則先執行IN里面的子查詢,再查詢外層的表記錄,如果轉換成功則直接采用多個表的連接方式查詢。由此可見用IN的SQL至少多了一個轉換的過程。一般的SQL都可以轉換成功,但對于含有分組統計等方面的SQL就不能轉換了。
    推薦方案:在業務密集的SQL當中盡量不采用IN操作符,用EXISTS 方案代替。
    2、NOT IN操作符
    此操作是強列不推薦使用的,因為它不能應用表的索引。
    推薦方案:用NOT EXISTS 方案代替
    3、IS NULL 或IS NOT NULL操作(判斷字段是否為空)
    判斷字段是否為空一般是不會應用索引的,因為索引是不索引空值的。
    推薦方案:用其它相同功能的操作運算代替,如:a is not null 改為 a>0 或a>’’等。不允許字段為空,而用一個缺省值代替空值,如申請中狀態字段不允許為空,缺省為申請。
    4、> 及 < 操作符(大于或小于操作符)
    大于或小于操作符一般情況下是不用調整的,因為它有索引就會采用索引查找,但有的情況下可以對它進行優化,如一個表有100萬記錄,一個數值型字段A,30萬記錄的A=0,30萬記錄的A=1,39萬記錄的A=2,1萬記錄的A=3。那么執行A>2與A>=3的效果就有很大的區別了,因為A>2時ORACLE會先找出為2的記錄索引再進行比較,而A>=3時ORACLE則直接找到=3的記錄索引。
    5、LIKE操作符
    LIKE操作符可以應用通配符查詢,里面的通配符組合可能達到幾乎是任意的查詢,但是如果用得不好則會產生性能上的問題,如LIKE ‘%5400%’ 這種查詢不會引用索引,而LIKE ‘X5400%’則會引用范圍索引。
    一個實際例子:用YW_YHJBQK表中營業編號后面的戶標識號可來查詢營業編號 YY_BH LIKE ‘%5400%’ 這個條件會產生全表掃描,如果改成YY_BH LIKE ’X5400%’ OR YY_BH LIKE ’B5400%’ 則會利用YY_BH的索引進行兩個范圍的查詢,性能肯定大大提高。
    6、UNION操作符
    UNION在進行表鏈接后會篩選掉重復的記錄,所以在表鏈接后會對所產生的結果集進行排序運算,刪除重復的記錄再返回結果。實際大部分應用中是不會產生重復的記錄,最常見的是過程表與歷史表UNION。如:
    select * from gc_dfys
    union
    select * from ls_jg_dfys
    這個SQL在運行時先取出兩個表的結果,再用排序空間進行排序刪除重復的記錄,最后返回結果集,如果表數據量大的話可能會導致用磁盤進行排序。
    推薦方案:采用UNION
    ALL操作符替代UNION,因為UNION ALL操作只是簡單的將兩個結果合并后就返回。
    select * from gc_dfys
    union all
    select * from ls_jg_dfys
    二、SQL書寫的影響
    1、同一功能同一性能不同寫法SQL的影響。
    如一個SQL在A程序員寫的為  Select * from zl_yhjbqk
    B程序員寫的為 Select
    * from dlyx.zl_yhjbqk(帶表所有者的前綴)
    C程序員寫的為 Select
    * from DLYX.ZLYHJBQK(大寫表名)
    D程序員寫的為 Select
    *  from DLYX.ZLYHJBQK(中間多了空格)
    以上四個SQL在ORACLE分析整理之后產生的結果及執行的時間是一樣的,但是從ORACLE共享內存SGA的原理,可以得出ORACLE對每個SQL 都會對其進行一次分析,并且占用共享內存,如果將SQL的字符串及格式寫得完全相同,則ORACLE只會分析一次,共享內存也只會留下一次的分析結果,這不僅可以減少分析SQL的時間,而且可以減少共享內存重復的信息,ORACLE也可以準確統計SQL的執行頻率。
    2、WHERE后面的條件順序影響
    WHERE子句后面的條件順序對大數據量表的查詢會產生直接的影響。如:
    Select * from zl_yhjbqk where dy_dj = '1KV以下' and xh_bz=1
    Select * from zl_yhjbqk where xh_bz=1 and dy_dj = '1KV以下'
    以上兩個SQL中dy_dj(電壓等級)及xh_bz(銷戶標志)兩個字段都沒進行索引,所以執行的時候都是全表掃描,第一條SQL的dy_dj = '1KV以下'條件在記錄集內比率為99%,而xh_bz=1的比率只為0.5%,在進行第一條SQL的時候99%條記錄都進行dy_dj及xh_bz的比較,而在進行第二條SQL的時候0.5%條記錄都進行dy_dj及xh_bz的比較,以此可以得出第二條SQL的CPU占用率明顯比第一條低。
    3、查詢表順序的影響
    在FROM后面的表中的列表順序會對SQL執行性能影響,在沒有索引及ORACLE沒有對表進行統計分析的情況下,ORACLE會按表出現的順序進行鏈接,由此可見表的順序不對時會產生十分耗服物器資源的數據交叉。(注:如果對表進行了統計分析,ORACLE會自動先進小表的鏈接,再進行大表的鏈接)
    三、SQL語句索引的利用
    1、操作符優化(同上)
    2、對條件字段的一些優化
    采用函數處理的字段不能利用索引,如:
    substr(hbs_bh,1,4)=’5400’,優化處理:hbs_bh like ‘5400%’
    trunc(sk_rq)=trunc(sysdate), 優化處理:sk_rq>=trunc(sysdate) and
    sk_rq<trunc(sysdate+1)
    進行了顯式或隱式的運算的字段不能進行索引,如:ss_df+20>50,優化處理:ss_df>30
    ‘X’ || hbs_bh>’X5400021452’,優化處理:hbs_bh>’5400021542’
    sk_rq+5=sysdate,優化處理:sk_rq=sysdate-5
    hbs_bh=5401002554,優化處理:hbs_bh=’ 5401002554’,注:此條件對hbs_bh 進行隱式的to_number轉換,因為hbs_bh字段是字符型。
    條件內包括了多個本表的字段運算時不能進行索引,如:ys_df>cx_df,無法進行優化
    qc_bh || kh_bh=’5400250000’,優化處理:qc_bh=’5400’ and kh_bh=’250000’
    四、其他
    ORACLE的提示功能是比較強的功能,也是比較復雜的應用,并且提示只是給ORACLE執行的一個建議,有時如果出于成本方面的考慮ORACLE也可能不會按提示進行。根據實踐應用,一般不建議開發人員應用ORACLE提示,因為各個數據庫及服務器性能情況不一樣,很可能一個地方性能提升了,但另一個地方卻下降了,ORACLE在SQL執行分析方面已經比較成熟,如果分析執行的路徑不對首先應在數據庫結構(主要是索引)、服務器當前性能(共享內存、磁盤文件碎片)、數據庫對象(表、索引)統計信息是否正確這幾方面分析。
     
    (繼續閱讀...)
    文章標籤

    AutoPoster 發表在 痞客邦 留言(0) 人氣(33)

    • 個人分類:生活學習
    ▲top
    «1...567230»

    pop-under

    參觀人氣

    • 本日人氣:
    • 累積人氣:

    線上人數

    Marquee

    最新文章

    • 文章列表
    • jvm系列(四):jvm調優-命令大全(jps jstat jmap jhat jstack jinfo)
    • spring boot(一):入門篇
    • jvm系列(一):java類的加載機制
    • jvm系列(三):java GC算法 垃圾收集器
    • spring boot 實戰:我們的第一款開源軟件
    • jvm系列(六):jvm調優-從eclipse開始
    • 混合應用技術選型
    • jvm系列(二):JVM內存結構
    • spring boot(五):spring data jpa的使用

    熱門文章

    • (1,763)jQuery之前端國際化jQuery.i18n.properties
    • (1,001)Oracle Hint
    • (630)技術筆記:Indy控件發送郵件
    • (515)linux下安裝sqlite3
    • (501)學習筆記: Delphi之線程類TThread
    • (242)VC單選按鈕控件(Radio Button)用法(轉)
    • (104)單條件和多條件查詢
    • (51)淺談config文件的使用
    • (22)基于 Asp.Net的 Comet 技術解析
    • (15)Java中的抽象類

    文章分類

    • 生活學習 (2,296)
    • 未分類文章 (1)

    最新留言

    • [20/04/24] 我是女生想約炮 有男生願意給我溫暖的嗎?我賴是woyou58 於文章「(1)從底層設計,探討插件式GIS框架的...」留言:
      我叫黎兒女生最近內心掙扎著要不要約炮我的line:woy...

    文章搜尋

    文章精選

    誰來我家

    Live Traffic Feed