Я не думаю, что класс SimpleMailMessage имеет такие параметры.
Я уверен, что вы можете сделать это с помощью JavaMailSender и MimeMessagePreparator, потому что вам нужно установить тип содержимого MIME для HTML.
См. эту ссылку для справки:
http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/mail.html
Ниже вы найдете несколько времен выполнения различных методов.
система:
- Процессор Intel (R) Core (TM) i5-6500T @ 2,50 ГГц
- размер кеша: 6144 КБ
- ОЗУ: 16 МБ
- GNU Fortran (GCC) 6.3.1 20170216 (Red Hat 6.3.1-3)
- ifort (IFORT) 18,0. 5 20180823
- BLAS: для компилятора gnu по умолчанию используется версия
:
[gnu] $ gfortran -O3 x.f90 -lblas [intel] $ ifort -O3 -mkl x.f90
Выполнение:
blockquote>[gnu] $ ./a.out > matmul.gnu.txt [intel] $ EXPORT MKL_NUM_THREADS=1; ./a.out > matmul.intel.txt
Чтобы результаты были как можно более нейтральными, я изменил размеры ответов с помощью среднее время эквивалентного набора выполненных операций. Я игнорировал потоки.
матричный вектор времени
Сравнивались шесть различных реализаций:
- руководство:
do j=1,n; do k=1,n; w(j) = P(j,k)*v(k); end do; end do
- matmul: [ 1186]
matmul(P,v)
- Блас N:
dgemv('N',n,n,1.0D0,P,n,v,1,0,w,1)
- matmul-transpose:
matmul(transpose(P),v)
- ] matmul-transpose-tmp:
Q=transpose(P); w=matmul(Q,v)
- blas T:
dgemv('T',n,n,1.0D0,P,n,v,1,0,w,1)
На рисунках 1 и 2 вы можете сравнить сроки результатов для вышеуказанных случаев. В целом мы можем сказать, что использование временного в
gfortran
иifort
не рекомендуется. Оба компилятора могут оптимизироватьMATMUL(TRANSPOSE(P),v)
намного лучше. В то время как вgfortran
реализацияMATMUL
быстрее, чем BLAS по умолчанию,ifort
ясно показывает, чтоmkl-blas
быстрее.рисунок 1: Умножение матрицы на вектор. Сравнение различных реализаций выполнено на
gfortran
. Левые панели показывают абсолютную синхронизацию, деленную на общее время ручного вычисления для системы размером 1000. Правые панели показывают абсолютную синхронизацию, деленную на n2 × δ. Здесь δ - среднее время ручного вычисления размера 1000, деленное на 1000 × 1000.рисунок 2: Умножение матрицы на вектор. Сравнение различных реализаций выполнялось на однопоточной компиляции
ifort
. Левые панели показывают абсолютную синхронизацию, деленную на общее время ручного вычисления для системы размером 1000. Правые панели показывают абсолютную синхронизацию, деленную на n2 × δ. Здесь δ - среднее время ручного вычисления размера 1000, деленное на 1000 × 1000.Матрица умножила матрицу
Шесть различных реализаций были сравнены:
- руководство:
do l=1,n; do j=1,n; do k=1,n; Q(j,l) = P(j,k)*P(k,l); end do; end do; end do
- matmul: [ 1194]
matmul(P,P)
- Блас N:
dgemm('N','N',n,n,n,1.0D0,P,n,P,n,0.0D0,R,n)
- matmul-transpose:
matmul(transpose(P),P)
- [1197 ] matmul-transpose-tmp:
Q=transpose(P); matmul(Q,P)
- blas T:
dgemm('T','N',n,n,n,1.0D0,P,n,P,n,0.0D0,R,n)
На рисунках 3 и 4 вы можете сравнить сроки результатов для вышеуказанных случаев. В отличие от вектора-случая, использование временного рекомендуется только для gfortran. В то время как в
gfortran
реализацияMATMUL
быстрее, чем BLAS по умолчанию,ifort
ясно показывает, чтоmkl-blas
быстрее. Примечательно, что ручная реализация сравнима сmkl-blas
.Рисунок 3: Матрично-матричное умножение. Сравнение различных реализаций выполнено на
gfortran
. Левые панели показывают абсолютную синхронизацию, деленную на общее время ручного вычисления для системы размером 1000. Правые панели показывают абсолютную синхронизацию, деленную на n3 × δ. Здесь δ - среднее время ручного вычисления размера 1000, деленное на 1000 × 1000 × 1000.рисунок 4: Матрично-матричное умножение. Сравнение различных реализаций выполнялось на однопоточном компиляторе
ifort
. Левые панели показывают абсолютную синхронизацию, деленную на общее время ручного вычисления для системы размером 1000. Правые панели показывают абсолютную синхронизацию, деленную на n3 × δ. Здесь δ - среднее время ручного вычисления размера 1000, деленное на 1000 × 1000 × 1000.
Используемый код:
program matmul_test implicit none double precision, dimension(:,:), allocatable :: P,Q,R double precision, dimension(:), allocatable :: v,w integer :: n,i,j,k,l double precision,dimension(12) :: t1,t2 do n = 1,1000 allocate(P(n,n),Q(n,n), R(n,n), v(n),w(n)) call random_number(P) call random_number(v) i=0 i=i+1 call cpu_time(t1(i)) do j=1,n; do k=1,n; w(j) = P(j,k)*v(k); end do; end do call cpu_time(t2(i)) i=i+1 call cpu_time(t1(i)) w=matmul(P,v) call cpu_time(t2(i)) i=i+1 call cpu_time(t1(i)) call dgemv('N',n,n,1.0D0,P,n,v,1,0,w,1) call cpu_time(t2(i)) i=i+1 call cpu_time(t1(i)) w=matmul(transpose(P),v) call cpu_time(t2(i)) i=i+1 call cpu_time(t1(i)) Q=transpose(P) w=matmul(Q,v) call cpu_time(t2(i)) i=i+1 call cpu_time(t1(i)) call dgemv('T',n,n,1.0D0,P,n,v,1,0,w,1) call cpu_time(t2(i)) i=i+1 call cpu_time(t1(i)) do l=1,n; do j=1,n; do k=1,n; Q(j,l) = P(j,k)*P(k,l); end do; end do; end do call cpu_time(t2(i)) i=i+1 call cpu_time(t1(i)) Q=matmul(P,P) call cpu_time(t2(i)) i=i+1 call cpu_time(t1(i)) call dgemm('N','N',n,n,n,1.0D0,P,n,P,n,0.0D0,R,n) call cpu_time(t2(i)) i=i+1 call cpu_time(t1(i)) Q=matmul(transpose(P),P) call cpu_time(t2(i)) i=i+1 call cpu_time(t1(i)) Q=transpose(P) R=matmul(Q,P) call cpu_time(t2(i)) i=i+1 call cpu_time(t1(i)) call dgemm('T','N',n,n,n,1.0D0,P,n,P,n,0.0D0,R,n) call cpu_time(t2(i)) write(*,'(I6,12D25.17)') n, t2-t1 deallocate(P,Q,R,v,w) end do end program matmul_test