2009-08-18 16 views
9

Tôi đang ở trong phần có hiệu suất rất nhạy cảm với mã của tôi (C#/WPF) và tôi cần thực hiện thao tác mô-đun giữa hai giá trị System.TimeSpan theo cách nhanh nhất có thể.Làm thế nào tôi có thể đạt được một hoạt động mô-đun với các giá trị System.TimeSpan, không có vòng lặp?

Mã này sẽ chạy hàng nghìn lần mỗi giây và tôi rất muốn tránh sử dụng tính toán vòng lặp thủ công - bằng mọi giá.

Ý tưởng về một mô đun giữa hai timespans có vẻ hơi lạ, vì vậy cho phép tôi giải thích -
Giả sử chúng ta có
TimeSpan A = 1 Minute 30 Giây
TimeSpan B = 20 Giây

đây sẽ là một danh sách các hoạt động phổ biến và kết quả hợp lý của họ:

A + B = (TimeSpan) 1 Minute 50 Giây

A - B = (TimeSpan) 1 Minute 10 Giây

A * B = Không có cách hợp lý để tính
Chúng tôi sẽ có thể nhân một TimeSpan cho một số nguyên. A * 5 = (TimeSpan) 7 phút 30 giây
Microsoft chưa triển khai phép nhân giữa TimeSpans và số nguyên.

A/B = (int) 4 hoặc (double) 4.5
Thao tác này không được triển khai trực tiếp trong khuôn khổ .NET, nhưng nó có ý nghĩa hoàn hảo.
Có của 4,5 B trong A. (4,5 * 20 = 90)

A% B = (TimeSpan) 10 Giây
Với bộ phận TimeSpan hợp lý, TimeSpan mô đun nên được khá thẳng về phía trước.
A/B thực sự bằng (int) 4 phần còn lại (TimeSpan) 10 Giây. Thương lượng và số dư còn lại là các loại dữ liệu khác nhau, mà thực tế có thể là lý do tại sao Microsoft không triển khai trực tiếp điều này.

Tôi cần tìm một cách hiệu quả để tính toán điều này mà không lặp. Thông thường tôi sẽ không phản đối một vòng lặp ngắn, nhưng những TimeSpans này có thể khác nhau rất nhiều. Sự khác biệt theo hàm mũ lớn hơn giữa các TimeSpans, lớn hơn thương. Thương số càng lớn thì càng có nhiều vòng lặp "phân chia vòng lặp" sẽ phải thực thi. Đây là một sự phụ thuộc mà tôi không thể cho phép trong phần này của ứng dụng của tôi.

SO có ý tưởng nào không?

+0

Câu trả lời rất đơn giản. Tôi cảm thấy như một dunce, haha. Cảm ơn SO! – Giffyguy

+1

Mọi thứ trở nên đơn giản khi bạn có câu trả lời. –

Trả lời

23

Phép nhân là dễ dàng:

TimeSpan a5 = TimeSpan.FromTicks(A.Ticks * 5); 

Tương tự như vậy A/B:

double aOverB = (double)A.Ticks/B.Ticks; 

Và A% B:

TimeSpan aModB = TimeSpan.FromTicks(A.Ticks % B.Ticks); 

diễn:

using System; 

class Test 
{ 
    static void Main() 
    { 
     TimeSpan a = TimeSpan.FromSeconds(90); 
     TimeSpan b = TimeSpan.FromSeconds(20); 

     TimeSpan a5 = TimeSpan.FromTicks(a.Ticks * 5); 
     double aOverB = (double)a.Ticks/b.Ticks; 
     TimeSpan aModB = TimeSpan.FromTicks(a.Ticks % b.Ticks); 

     Console.WriteLine(a5); 
     Console.WriteLine(aOverB); 
     Console.WriteLine(aModB); 
    } 
} 

Đầu ra:

00:07:30 
4.5 
00:00:10 
+0

sẽ không tạo ra một tấn vật thể đang chờ xử lý rác thải? Sẽ không theo dõi thời gian bằng cách sử dụng mili giây hoặc bọ ve như là một dài được tốt hơn cuối cùng? – ADB

+6

TimeSpan là một cấu trúc và do đó sẽ không đốt cháy GC. – user7116

4

Nếu bạn có thể chuyển đổi từ khoảng thời gian sang số giây mà nó đại diện, bạn có thể sửa đổi các giá trị đó và sau đó chuyển đổi lại.

5

Would cái gì đó như

new TimeSpan(A.Ticks % B.Ticks)) 

cung cấp cho bạn kết quả bạn muốn? Ticks sẽ là đơn vị phù hợp để thực hiện công việc? Có thể bạn cần phải chuyển đổi khoảng thời gian thành giây hoặc mili giây hoặc thứ gì đó. Tôi không biết ứng dụng của bạn là gì.

3

Tôi sẽ không làm điều này trực tiếp với đối tượng timepan, nhưng sử dụng khả năng đánh dấu.

Điều gì đó tương tự.

TimeSpan oSpan = new TimeSpan(0, 1, 20, 0, 0); 
TimeSpan oShort = new TimeSpan(0, 0, 20, 0, 0); 
long modRemainder = oSpan.Ticks % oShort.Ticks; 
TimeSpan oRemainderSpan = new TimeSpan(modRemainder); 

Bạn có thể ngưng tụ, thành 1 bước, nhưng tôi đã làm điều này để minh họa. Nó làm cho nó tốt đẹp và dễ dàng để làm bất kỳ hoạt động toán học mà bạn mong muốn.

1

Điều tốt nhất tôi có thể nghĩ là sử dụng Thuộc tính Tổng số giây và điều chỉnh nó. Tuy nhiên, chúng là Double, cho phép các giá trị phân số và do đó, có thể không đạt được các giá trị chính xác mà bạn đang tìm kiếm. Bạn luôn có thể nhận được toàn bộ các phần và điều chỉnh chúng nhưng vì bạn lo lắng về tốc độ, tôi lo sợ điều này có thể quá chậm đối với một hoạt động phải chạy hàng trăm lần trong một giây.

Các vấn đề liên quan