2014년 3월 21일 금요일

INotifyPropertyChanged Test

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApplication6 {
    public partial class UCtlCompA : UserControl, 
                                     INotifyPropertyChanged {
        public UCtlCompA() {
            InitializeComponent();
            this.textBox2.DataBindings.Add("Text", 
                                           this, 
                                           "SumName", 
                                           false, 
                                           DataSourceUpdateMode.OnPropertyChanged);
        }

        private void txtTitle_TextChanged(object sender, EventArgs e) {
            ProdName = txtTitle.Text;
            SumName = ProdName + " / " + UserName;
        }

        private void textBox1_TextChanged(object sender, 
                                          EventArgs e) {
            UserName = textBox1.Text;
            SumName = ProdName + " / " + UserName;
        }

        private void NotifyPropertyChanged([CallerMemberName] String propertyName = "") {
            if (PropertyChanged != null) {
                PropertyChanged(this, 
                                new PropertyChangedEventArgs(propertyName));
            }
        }

        public string ProdName {
            get { return this._prodname; }
            set {
                if (value != this._prodname) {
                    this._prodname = value;
                    NotifyPropertyChanged();
                }
            }
        }

        public string UserName {
            get { return this._username; }
            set {
                if (value != this._username) {
                    this._username = value;
                    NotifyPropertyChanged();
                }
            }
        }

        public string SumName {
            get { return this._sumname; }
            set {
                if (value != this._sumname) {
                    this._sumname = value;
                    NotifyPropertyChanged();
                }
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        private string _prodname = string.Empty;
        private string _username = string.Empty;
        private string _sumname = string.Empty;

    }
}

2014년 3월 18일 화요일

.Net Framework SourceCode 살펴보기

어찌보면 MS는 대단한 대인배인 듯 하다.
물론 .net Reflactor 같은 것을 이용하면 되겠지만
남이 하는 거와 그냥 내 걸 볼 수 있게 아예 사이트를 만들어 놓는 건 좀 다른 듯 하다.

아무튼 .Net Framework의 소스를 쭉 살펴볼 수 있는 공식 사이트...

http://referencesource.microsoft.com/

2014년 3월 13일 목요일

Performance Profiler by RealProxy

http://vunvulearadu.blogspot.kr/2014/02/aop-using-realproxy-custom.html
위에서 제시된 코드를 기반으로(사실 똑같다)
내 손으로 다시 쳐서 구현해본 코드이다.

PostSharp보다 좀 불편해보이는 방식이긴 한데
Pre-Processing되는 PostSharp의 경우
간혹 불안정하게 동작하는 경우가 있고
이를 해결할 방법이 뾰족하게 없으나
이렇게 직접 코드를 작성하는 경우는
결국 안정성은 본인의 몫이기 때문에 잘만 한다면
PostSharp보다 나을도 있겠다 싶다.

 물론 상용Tool인 PostSharp은 좋은 제품인 건 맞다.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.Remoting.Proxies;
using System.Runtime.Remoting.Messaging;

namespace AOPWithRealProxy {
    class Program {
        static void Main(string[] args) {
            PerfProfilingDynamicProxy<itest> testProfiling 
                 = new PerfProfilingDynamicProxy<itest>(new Test());
            ITest test = (ITest)testProfiling.GetTransparentProxy();

            test.TestMethod();

            Console.ReadLine();
        }
    }

    public class PerfProfilingDynamicProxy : RealProxy {
        public PerfProfilingDynamicProxy(T decorated)
            : base(typeof(T)) {
                _decorated = decorated;
        }

        public override IMessage Invoke(IMessage msg) {
            IMethodCallMessage methodcall = (IMethodCallMessage)msg;
            MethodInfo methodInfo = methodcall.MethodBase as MethodInfo;
            PerfProfilingAttribute profilingAttribute 
                 = (PerfProfilingAttribute)methodInfo.GetCustomAttributes(typeof(PerfProfilingAttribute)).FirstOrDefault();
            if(profilingAttribute == null) {
                return NormalInvoke(methodInfo, methodcall);
            }
            else {
                return ProfiledInvoke(methodInfo, 
                                      methodcall, 
                                      profilingAttribute.Message);
            }
        }

        private IMessage NormalInvoke(MethodInfo methodInfo, 
                                      IMethodCallMessage methodCall) {
            try {
                var result = methodInfo.Invoke(_decorated, methodCall.InArgs);
                return new ReturnMessage(result, 
                                         null, 
                                         0, 
                                         methodCall.LogicalCallContext, 
                                         methodCall);
            }
            catch(Exception err) {
                return new ReturnMessage(err, methodCall);
            }
        }

        private IMessage ProfiledInvoke(MethodInfo methodInfo, 
                                        IMethodCallMessage methodCall, 
                                        string attrMessage) {
            Stopwatch sw = null;
            try {
                sw = Stopwatch.StartNew();
                var result = methodInfo.Invoke(_decorated, methodCall.InArgs);
                sw.Stop();
                Console.WriteLine(sw.ElapsedMilliseconds);
                long tick = sw.ElapsedTicks;
                return new ReturnMessage(result, 
                                         new object[] { tick }, 
                                         1, 
                                         methodCall.LogicalCallContext, 
                                         methodCall);
            }
            catch(Exception err) {
                return new ReturnMessage(err, methodCall);
            }
            finally {
                if(sw != null && sw.IsRunning) {
                    sw.Stop();
                }
            }
        }

        private readonly T _decorated;
    }

    public class PerfProfilingAttribute : Attribute {
        public PerfProfilingAttribute(string message) {
            Message = message;
        }

        public PerfProfilingAttribute() {
            Message = string.Empty;
        }

        public string Message { get; set; }
    }

    public interface ITest {

        [PerfProfiling]
        DateTime TestMethod();
    }

    public class Test : ITest {
        public DateTime TestMethod() {
            double sumv = 0.0;
            for(int i = 0; i < 100000; i++) {
                Random rnd = new Random(575);
                sumv += rnd.NextDouble();
            }
            return DateTime.Now;
        }
    }
}

2014년 3월 11일 화요일

Distributed Caching

http://msdn.microsoft.com/en-us/magazine/dd942840.aspx

실제 훌륭한 .Net용 Distributed Cache 솔루션을 가지고 있는
NCache사 사장 (사장이 이런 내용의 글을 쓰다니...,
우리가 알고 있는 그런 "관리의 사장"은 아닌 듯)
이 작성한 글이다.
딱 느낌이 많이 해본 솜씨...

실제로 이 부분을 작업하면서 항상 부딪쳤던 문제들인데
잘 정리해둔 것 같다.
특히 Caching Relational Data 부분은 미리 알았더라면
많은 수고를 들 수 있었던 부분이 아닌가 싶다.


2014년 3월 9일 일요일

MAF & MEF

MAF(Managed AddIn Framework)은 .net Framework 위에서
AddIn을 구성할 수 있는Framework을 제공하고 있고,
MEF(Managed Extensibility Framework)은 AddIn보다
더 확장성 있게 추가기능 형태를 구현할 수 있게 제공하고 있는 Framework인 듯 하다.

 그냥 개인적인 생각에는 MAF가 3.5에서 나왔고,
실제 사용하는 와중에 무겁거나 복잡하거나해서
좀 더 간편하게 사용할 수 있는 방식으로 4.0에서 구현해둔게 MEF가 아닌가 싶기도 하다. 

아무튼 MAF에 관련된 괜찮은 Article이 CodeProject에 있다.
정말 CodeProject는 프로그래밍에 관련해서는 없는게 없는 곳이지 않나 싶다.

  http://www.codeproject.com/Articles/25866/AddIn-Enabled-Applications

2014년 3월 5일 수요일

금융관련 날짜 계산

다소 오래되긴 했으나 금융관련 날짜 계산에 필요한 기능을 구현해놓은
OpenSource 프로젝트이다.
스케쥴(Cashflow)생성에 관련된 함수들이 어느 정도 정리되어 있으므로
참조하면 좋을 듯...


http://sourceforge.net/p/jfin/code/HEAD/tree/branches/A_0_0_5_dave/src/main/java/org/jfin/

WCF Performance 올리기

WCF Service의 경우 다양한 Binding과 수많은 옵션들로 인해 Performance가
천차만별이다.

특히 개발단계에서 보면 예상하지 못한 낮은 Performance로
고생하는 경우들이 많다.

아래 글은 특히 netTcpBinding을 사용하는 경우
Performance를 향상시킬 수 있는 방법,
그리고 종종 실수하게 되는 Debug모드와 Release모드간의
극단적인 Performance차이에 대해 설명하고 있다.


http://blog.shutupandcode.net/?p=1085

추가로 "IT Expert, 유수석의 WCF 바이블"(유경상)이란 책을 읽어보면 좋을 듯 하다.
책값이 비싸지만 괜찮은 책이라는 이야기를 많이 들었다.
아니면 과천도립도서관에서 대출받는 것도 방법...
근데 없으면? <해당 사이트가 사라진 듯 하여 저장된 페이지 추가>

High Performance WCF Services : netTcpBinding

By Terrance A. Snyder On April 12, 2010 · 15 Comments · In .NET
A bit of a divergence away from Azure today. I had two questions I wanted to answer before running comparison of performance in Azure.

I received some requests for some down-loadable source. It can be downloaded here: NetTcpBindingExample

How fast can WCF go? How about ~29,000 requests per second?

Ah, the eternal question… The benefit of finding the answer is that it puts some sanity checks in place whenever we are planning our architecture. If a business user wants to have two million transactions processed in a minute can you do this with WCF? What about 1 hour? What about 24 hours? Somewhere in there is a “yes we can do this”, but alas, unless you read on you wont know where to start…

Further if you don’t know the absolute fastest WCF can perform how do you know if you are running ‘slow’ or ‘good’. What about how many servers you may need? Baselines are great tools… read on…

WCF Binding Comparisons

Below charts show the comparison of basicHttpBinding, binaryHttpBinding, and netTcpBinding.

One Way Operations with Basic String (Calls Made Per Second)
Compare2

Large Object Operation with Complex Object (Calls Made Per Second)
Compare

By far the best channel is netTcpBinding for performance – both for large objects and one-way operations. You’ll note the benefit of binaryHttpBinding over basicHttpBinding is not apparent when dealing with small objects. This makes sense considering the network savings aren’t in play for our simple string operation.

The Service Tested

To answer “the fastest” question and to do sanity checks the below was the service interface created.

view sourceprint?
01.[ServiceBehavior(
02.    ConcurrencyMode=ConcurrencyMode.Multiple,
03.    InstanceContextMode=InstanceContextMode.Single,
04.    AddressFilterMode=AddressFilterMode.Any)]
05.public class HelloWorldService : IHelloWorldService
06.{
07.    public void MockOneWayOperation(string name)
08.    {
09.          // do absolutely nothing
10.    }
11. 
12.    public CompositeType MockTwoWayOperation(CompositeType composite)
13.    {
14.        return composite;
15.    }
16.}
You will note that this service does absolutely nothing. We took out database calls, or any other dependency… Its the simplest and most pure service ever… you can’t make a faster service so it’s good in that it eliminates any external dependency (save network).

It is recommended that you always call Channel.Open()

On top of just the binding chosen you have one more thing to worry about (well two to be exact). If you are calling a WCF service please be sure to call yourclient.open(); explicitly before actually calling a service operation.

Calling svc.Open() on netTcpBinding helps, please do it… your mom will thank you
netTcpBinding_Small

Calling svc.Open() on WCF BasicHttpBinding helps a lot as you can see below
BasicHttpBinding_Small

Configuration of net.tcp when running in port sharing mode:
http://msdn.microsoft.com/en-us/library/aa702669.aspx

Note: When running your WCF services in netTcpBinding using port sharing the configuration of the netTcpBinding is ignored. You must change these settings as described in the above MSDN document to get maximum throughput.

My performance isn’t that good?! What voodoo are you using?!

Please be sure when running your tests you answer NO to both these questions:

Is your web.config in debug mode?
Is your test client running in debug?

Running with any of the above is a recipe for disappointment. As an example of how much of a disappointment you are in for, the below chart shows the potential performance hit you will take if you have either the server or the client in debug (or both).

Keep in mind this is the same high performance netTcpBinding!

The only thing I am doing here is running the service in debug and the client tester (VS Unit Test) in debug.

Note the extreme difference in performance when client is running in debug
debug

When measuring performance please be sure your WCF service is not running in debug (web.config) and your client is not running in debug. If you are using a Visual Studio Unit Test for quick performance evaluation be sure to run the unit test as “Run Selection”, not “Debug Selection”.

Measurements

table

As you can see the running debug+debug without server GC on the fastest WCF binding will cause you to be running 29x slower than you would otherwise expect.

Maximum Performance WCF netTcpBinding Configuration…

No security, no reliable sessions, max serialization, max listen backlog.

view sourceprint?
01.
02.  
03.    
04.      
08.    
09.  
10.  
11.    
12.      
20.        
21.          
22.          
23.        
24.        
25.      
26.    
27.  
28.  
29.    
30.      
31.        
32.        
33.      
34.    
35.  
36.
37.
38.  
39.
40.
41.  
42.
 
If you enjoyed this article, please consider sharing it!
15 Responses to High Performance WCF Services : netTcpBinding

Alik Levin says:
April 12, 2010 at 12:56 pm
very nice! i love the flow and the details. it goes to my personal KB under WCF/Perf ;)

Reply
Terrance A. Snyder says:
January 7, 2011 at 7:43 pm
Thanks! Feedback is always appreciated.

Reply
Tweets that mention Terrance A. Snyder -- Topsy.com says:
April 12, 2010 at 6:05 pm
[...] This post was mentioned on Twitter by Solidsoft. Solidsoft said: Terrance A. Snyder: It is important to note that when running your wcf services in net.tcp you're configuratio… http://bit.ly/b4vTq0 #WCF [...]

Reply
James Wilson says:
September 1, 2010 at 8:59 am
Excellent article! Your conclusions are well documented and the article is very down-to-earth and easy to understand. Well done.

Reply
Terrance A. Snyder says:
January 7, 2011 at 7:43 pm
Thank you.

Reply
Tom Boring says:
September 1, 2010 at 9:25 am
Great article! Jim (Wilson) had always told us (the folk he USED to work with) how fast netTCP was, but he never proved it. Of course, we trusted him…but then he left to work for some other company.

Reply
Terrance A. Snyder says:
January 7, 2011 at 7:43 pm
Sorry to hear about the loss of a valuable member. Always come prepared to back things up with metrics and for management types always show the classic bar chart of performance. Reduce the decision down to one slide and make it obvious what to do.

Reply
k9 says:
December 15, 2010 at 1:38 pm
nice article , I try to use the same netTcpBinding “ultra” for the client side proxy configuration and I had some errors relates to out of memory issues .

Reply
Valeriano Cossu says:
December 26, 2010 at 4:36 am
Very clear, I am going to use it.

Reply
Terrance A. Snyder says:
January 7, 2011 at 7:44 pm
Good to hear, make sure you check out the codeplex P&P book http://wcfsecurityguide.codeplex.com/

Reply
Konstantin says:
January 20, 2011 at 3:42 am
Hi, Terrance!
I wonder, what was the hardware you used to perform that benchmarks?

Did you used a gigabit network between client and server? How many CPU codes were in the server?

Thanks in advance.

Reply
Terrance A. Snyder says:
February 14, 2011 at 8:34 am
A simple Dual-core LGA995. Windows 2003 Server. Tests were run locally so client and server were running on same to remove network from equation. This was merely a test for “the fastest possible” on a CPU side. Of course smaller objects being transmitted would also mean that the binary would also be more efficient.

Thats the great thing about WCF, you can have both on at the same time (at least in Windows 2003 R2) so for internal communications use binary and external using SOAP/XML.

Reply
Gustavo says:
April 12, 2011 at 7:58 am
Hi Terrance, this is an interesting article. However I have a question, in the test you seem to be reusing the client in all the requests, and in real life, I would be creating a new client everytime I need to call the service. Do you know how creating a new client per request would impact the performance/numbers?
Thanks

Reply
Adactus - Official Blog | PERFORMANCE TUNING WCF says:
December 14, 2011 at 6:26 pm
[...] excellent article on WCF performance, from Terrance A. Snyder, shows the performance of various binding options in [...]

Reply
Maxim says:
January 1, 2012 at 10:15 am
Hi,

Great article!

About the .Open() – Do you mean to call it on the ChannelFactory or on the Client proxy?

Do you have an idea what the .Open() method does?

Reply

2014년 3월 4일 화요일

DayCount Conventions

1. 30/360 Method
이 방법은 다음의 방식으로 계산되는 DayCount Convention이다.
 (360 * (Y2 - Y1) + 30 * (M2 - M1) + (D2 - D1)) / 360

 2. 30/360
 (360 * (Y2 - Y1) + 30 * (M2 - M1) + (D2 - D1)) / 360
만일 D1이 31일이면 D1을 30일로 바꾼다.
만일 D2가 31일이고, D1이 30일 혹은 31일이면 D2를 30일로 바꾼다.

 3. 30E/360
 (360 * (Y2 - Y1) + 30 * (M2 - M1) + (D2 - D1)) / 360
만일 D1이 31일이면 D1을 30일로 바꾼다.
만일 D2가 31일이면 D2를 30일로 바꾼다.

 4. 30E/360(ISDA)
 (360 * (Y2 - Y1) + 30 * (M2 - M1) + (D2 - D1)) / 360
만일 D1이 그 달의 마지막날이라면 D1을 30일로 바꾼다.
만일 D2가 2월의 마지막날이지만 Termination Date가 아니거나 D2가 31일이면 D2를 30일로 바꾼다.

 5. 30E+/360(ISDA)
 (360 * (Y2 - Y1) + 30 * (M2 - M1) + (D2 - D1)) / 360
만일 D1이 31일이면 D1을 30일로 바꾼다.
만일 D2가 31일이면 D2를 1로 바꾸고 M2를 M2 + 1로 바꾼다.

 6. ACT/360
(d2 - d1) / 360
* (d2 - d1 : number of days between the two dates)

7. ACT/365 Fixed
(d2 - d1) / 365

8.ACT/365L
세개의 날짜가 필요
d1 : Coupon Start Day
d2 : Accrual Factor Day
d3 : Coupon End Day

Semi-Annual Coupon의 경우
(d2 - d1) / (Days in end year)
*Days in end year : d3가 leap year인 경우 366, 그렇지 않은 경우 365

Annual Coupon의 경우
(d2 - d1) / Denominator
* Denominator : 2월 29일이 d1(미포함)과 d3(포함)사이에 있는 경우 366, 그렇지 않은 경우 365

9.ACT/365A
(d2 - d1) / Denominator
* Denominator : 2월 29일이 d1(미포함)과 d2(포함)사이에 있는 경우 366, 그렇지 않은 경우 365

10. NL/365
Numerator / 365
* Numerator : 2월 29일이 d1(미포함)과 d2(포함)사이에 있는 경우 d2 - d1 - 1, 그렇지 않은 경우 d2 - d1

11. ACT/ACT365 ISDA
(Days in a non-leap year / 365) + (Days in a leap year / 366)
기간 중 첫날은 포함, 마지막날은 제외
ex)2011-12-30 ~ 2012-01-02 인 경우 2/365 + 1/366 으로 계산

12. ACT/ACT ICMA
(1/freq)*Adjustment
Adjustment -> 추가적인 정리가 필요
 - None
 - Short at Start
 - Long at Start
 - Short at End
 - Long at End

13. Business/252
 Business Days / 252
기간 중 첫날은 포함, 마지막 날은 제외

2014년 3월 3일 월요일

Refactoring to Patterns

도서관에서 전산관련 책장을 뒤지다 "Refactoring to Pattern" 책을 빌렸다.
Refactoring에 대해 잘 알지 못하나 읽다보니 평소에 부닥치던 문제에 대한 나름의
해법들을 제시하고 있다.

한 150Page 정도 읽다가 도서관 반납일이 다된 관계로 반납하였으나
이 분야에 짧으나 바이블 같은 책 하나 구해서 읽어보고 다시 이 책을 읽으면
꽤나 도움이 되겠구나 싶다.

2014년 3월 1일 토요일

Syntax Highlighter

Programming을 다루는 블로그에서 Syntax Highlighter는 당연한 기능이지 싶다. 그래서 찾아본 결과 이미 쉽게 이를 블로그에 적용할 수 있게 만들어둔 것이 있다.

구글 Blogger에 첨부하는 방법을 쉽게 설명해둔 싸이트 http://oneqonea.blogspot.kr/2012/04/how-do-i-add-syntax-highlighting-to-my.html

해당 싸이트를 잘 보고 따라하면 쉽게 Blogger에서 Syntax Highlighter를 사용할 수 있다.
아래는 테스트 Code
using System;

public static void main(string[] args) {
  Console.WriteLine("Hello?");
}

.Net Reflector 대체제

앞선 글을 읽다보면 .net Reflector에 관련된 이야기가 나온다.
컴파일된 실행파일을 Decompiling해서 원래 소스코드로 전환해주는 프로그램으로
유명한 .net Reflector가 그것이다.

그런데 원래 Freeware였던 이 프로그램이 다른 상용업체(redgate)에 인수합병되면서
상용프로그램으로 변경되었다.
그리 비싸진 않지만(Standard : 95$, Pro 199$) 그래도 상용이다 보니 늘상 사용하는
경우가 아니면 구매하기 쉽지 않다.

적당한 대체제를 찾다보니 원하는 바를 딱 맞게 분석해놓은 글이 있다.
Alternative for .net Reflector

이 글에 따르면 IL Spy(http://wiki.sharpdevelop.net/ILSpy.ashx) 가
가장 적절한 대체제인 듯 하다.
실제로 IL Spy 사이트에 가서 받아사용해보니 적절하게 Decompiling 해주는 듯 하다.

물론 늘상 Decompiler를 사용하는 사람이라면 .Net Reflector를 이용하는 것이
바람직하겠지만 어쩌다 한번씩 사용하는 사람이라면 IL Spy를 사용하는 것도 괜찮을 듯 하다.

[.Net] StringBuilder 내부구조 변화

.net StringBuilder 내부구조가 변경되었나 보다.
StringBuilder 다시보기 (at SimpleIsBest.Net)
프로그래밍하다보면 제일 많이 사용하는 함수 중 하나가 이 함수이다.

그러고 보니 이 글이 작성되게 된 원인과 분석내용(아래)을 읽다보니
예전에 유사한 경우를 마주한 적이 있었던 기억이 난다.
.net의 StringBuilder가 너무해 by 미친병아리 (원인)
StringBuilder 에서의 OutOfMemoryException 오류 원인 분석 (분석)

결론적으로는 이제는 StringBuilder가 과다한 메모리를
순간적으로 사용하지는 않는다는 것,
그리고 여전히 StringBuilder 초기화 시점에 Capacity를 지정해주는 것이
바람직하다는 것이 되겠다.

fpML


Version 5.6 Recommendation이 Release 되었다.
CodeList가 잘 정리되어 있어 이를 Enumeration Data에 적용하기 좋을 듯...