2012-01-16 22 views
7

Tôi đang sử dụng định dạng này ngày đơn giảnSimpleDateFormat mất nhiều thời gian khi múi giờ được bao gồm

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS Z"); 

vấn đề là khi tôi sử dụng này phải mất quá nhiều thời gian để chuyển đổi thời gian, trong logcat tôi nhìn thấy một cái gì đó như thế này

I/Resources(4284): Loaded time zone names for en in 272ms. 
I/Resources(4284): Loaded time zone names for en in 194ms. 
I/Resources(4284): Loaded time zone names for en in 112ms. 
I/Resources(4284): Loaded time zone names for en in 111ms. 
I/Resources(4284): Loaded time zone names for en in 113ms. 
I/Resources(4284): Loaded time zone names for en in 127ms. 
I/Resources(4284): Loaded time zone names for en in 253ms. 
I/Resources(4284): Loaded time zone names for en in 110ms. 
I/Resources(4284): Loaded time zone names for en in 154ms. 
I/Resources(4284): Loaded time zone names for en in 112ms. 

làm thế nào tôi có thể sử dụng formater ngày đơn giản nhưng để tăng tốc độ những thứ lên, tôi không muốn mất ~ 150ms cho mọi chuyển đổi ...

có ai có vấn đề này trước đây chưa?

+0

đăng mã của bạn ... –

+0

Nếu đó là múi giờ làm chậm nó, bạn có thể tính toán nó một lần rồi thêm nó dưới dạng chuỗi cho mỗi định dạng, vì múi giờ không có khả năng thay đổi. – Jave

+0

đây là mã, độ trễ là trên SimpleDateFormat mới ("yyyy-MM-dd HH: mm: ss.SSS Z "), và đó là bởi vì tôi có vùng bao gồm, nếu tôi chạy mã của tôi với SimpleDateFormat mới (" yyyy-MM-dd HH: mm: ss.SSS "); [với múi giờ] nó hoạt động tốt , vấn đề duy nhất là khi múi giờ được bao gồm nó chỉ đơn giản là mất quá nhiều thời gian tôi không biết tại sao – Lukap

Trả lời

10

Điều này là do khởi tạo lười biếng của các chuỗi múi giờ. Chỉ cuộc gọi đầu tiên sẽ diễn ra trong thời gian dài. Nếu SimpleDateFormat được sử dụng lại sau đó, nó được tải xuống từ bộ nhớ cache và không nên mất nhiều thời gian hơn nữa.

Trước khi điều này được thay đổi, nó đã được thực hiện khi lớp học được tải và do đó bắt đầu hoạt động mất 2-3 giây nữa. Điều này có tác động xấu hơn nhiều đến trải nghiệm của người dùng so với nếu mất vài giây khi nó thực sự được sử dụng lần đầu tiên. Vấn đề là không có cách nào ngay bây giờ để phá vỡ vấn đề này do thiết kế của api SimpleDateFormat. Chỉ những điện thoại nhanh hơn mới có thể khắc phục điều này bằng cách chỉ mất ít hơn thời gian để thu thập các chuỗi đó.

Việc lưu vào bộ nhớ cache xảy ra trong các DateFormatSymbols mà SimpleDateFormat đang sử dụng. Bằng cách sử dụng lại trường hợp đó, có thể chỉ phải tải các lần đốt một lần (cho số cùng loại). Bạn cũng có thể tạo Instance đó trong một thread khi khởi động hoạt động để nó đã được lưu trữ khi nó được sử dụng. Để bắt đầu các chuỗi, hãy gọi .hashCode() để buộc khởi tạo bộ nhớ cache. Nhanh hơn một chút nhưng ít đơn giản hơn sẽ là để tuần tự hóa thể hiện. Điều này cũng buộc bộ nhớ cache được khởi tạo.

Tạm thời, hãy xem xét sử dụng AsyncTask để "khởi động" SimpleDateFormat trong quy trình của bạn trước khi bạn cần. Chỉ cần phân tích một số ngày trong AsyncTask doInBackground() để có được nó để tải các múi giờ đôi khi nó sẽ không ảnh hưởng đến người dùng rất nhiều. Khi được khởi tạo trong quá trình của bạn, SimpleDateFormat sẽ chạy nhanh cho đến khi quá trình của bạn bị chấm dứt.

+1

Có phải SimpleDateFormat cũng không an toàn trên Android? – Somatik

4

Điều này không đúng trên các bản phát hành gần đây của Android (và từ nội dung của thông điệp tường trình tôi có thể nói rằng bạn đang chạy bản phát hành cũ, bản phát hành hiện đại cho bạn biết thời gian đã dùng trong icu4c so với mã được quản lý) . Lưu ý rằng câu trả lời từ "Pulkit Goyal" được sao chép và dán từ http://code.google.com/p/android/issues/detail?id=3147 và văn bản đề cập đến Donut. Tôi đã viết lại mã này nhiều lần kể từ đó. Hiện tại, en_ và miền địa phương mặc định của hệ thống (tại thời điểm khởi động) được lưu trữ trong zygote. Có thêm bộ nhớ cache cho mỗi ứng dụng để cho các ngôn ngữ khác, bạn chỉ nên thanh toán một lần.

Trường hợp xấu nhất trong bản phát hành hiện đại là nơi người dùng thay đổi ngôn ngữ mặc định của hệ thống. Nó sẽ yêu cầu khởi động lại zygote ("khởi động lại thời gian chạy" hoặc khởi động lại) để nhận các chuỗi múi giờ của miền địa phương mặc định mới được lưu trong bộ đệm mà chúng có thể được chia sẻ. (tôi đã mô tả hành vi này trong chú thích 11 về lỗi và được gửi kèm theo ICS.)

+0

Tôi thấy các báo cáo nhật ký này xảy ra nhiều lần, sau khi tôi tải một nguồn cấp dữ liệu RSS bằng thư viện HorrorRSS hoặc ROME. bất cứ điều gì là nhận được lưu trữ như các báo cáo đăng nhập được in mỗi khi tôi tải một nguồn cấp dữ liệu mới, ngay cả trong cùng một phương pháp gọi ngay sau khi một trong những khác.Điều lạ là tôi đang không sử dụng SimpleDateFormat.Tôi có một câu hỏi hoạt động mở về điều này trong trường hợp bạn tò mò: http://stackoverflow.com/questions/12762 478/android-loaded-time-zone-name-cho-en-in-ms –

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