# FizzBuzz in Fortran much slower than in C

**URL:** <https://fortran-lang.discourse.group/t/fizzbuzz-in-fortran-much-slower-than-in-c/2339>\
**Category:** Uncategorized\
**Created:** [November 26, 2021, 3:46pm UTC](https://fortran-lang.discourse.group/t/fizzbuzz-in-fortran-much-slower-than-in-c/2339 "2021-11-26T15:46:10Z")\
**Posts on this page:** 1\
**Showing post:** 12

<div class="post-metadata">

**Author:** ![FortranFan](https://avatars.discourse-cdn.com/v4/letter/f/96bed5/32.png) [@FortranFan](https://fortran-lang.discourse.group/u/FortranFan)\
**Post date:** [November 28, 2021, 6:30pm UTC](https://fortran-lang.discourse.group/t/fizzbuzz-in-fortran-much-slower-than-in-c/2339/12 "2021-11-28T18:30:11Z")

</div>

> [@Beliavsky](#):
>
> C.. is about 9 times faster. I assume faster I/O in C is the cause. Can anyone produce a faster Fortran FizzBuzz?

A request: will it be possible for someone to take the **defined IO** with a **derived type** case shown below and try it with **stream output** on a Linux system, while the **“FizzBuzz”** values are setup using coarrays? Intel API can be an option for this. And compare it with the Fortran sequential IO with an intrinsic type shown by @Beliavsky in the original post?

```Fortran
   use num_string_m, only : num_string_t
   character(len=*), parameter :: FIZZBUZZ = "FizzBuzz"
   character(len=*), parameter :: FIZZ = "Fizz"
   character(len=*), parameter :: BUZZ = "Buzz"
   integer, parameter :: N = 1000000000
   type(num_string_t), allocatable :: s(:)[:]
   logical :: div_3, div_5
   integer :: i, x, j, lun, istat
   x = N / num_images()
   allocate( s(x)[*] )
   sync all
   do concurrent ( i = 1:x )
      j = (this_image()-1)*x + i
      div_3 = mod( j, 3 ) == 0
      div_5 = mod( j, 5 ) == 0
      if ( div_3 .and. div_5 ) then
         s(i) = FIZZBUZZ
      else if ( div_3 ) then
         s(i) = FIZZ
      else if ( div_5 ) then
         s(i) = BUZZ
      else
         s(i) = j
      end if
   end do
   sync all
   if ( this_image() == 1 ) then
      open( newunit=lun, access="stream", form="formatted", status="scratch", iostat=istat )
      if ( istat == 0 ) then
         do i = 1, num_images()
            write( lun, fmt="(*(DT))", advance="no" ) s(:)[i]
         end do
      end if
   end if
end

```

The code toward the derived type:

> **Click for code**
>
> ## Module for numstring\_t
> 
> ```Fortran
> module num_string_m
> type :: num_string_t
> private
> character(len=digits(0)) :: s
> integer :: lens = 0
> contains
> private
> procedure, pass(this) :: assign_s
> procedure, pass(this) :: assign_n
> procedure, pass(dtv) :: write_s
> generic, public :: assignment(=) => assign_s, assign_n
> generic, public :: write(formatted) => write_s
> end type
> contains
> elemental subroutine assign_s( this, s )
> class(num_string_t), intent(inout) :: this
> character(len=*), intent(in) :: s
> this%s = s
> this%lens = len_trim(this%s) 
> end subroutine
> elemental subroutine assign_n( this, num )
> class(num_string_t), intent(inout) :: this
> integer, intent(in) :: num
> integer :: i, n, rem
> n = num
> this%s = ""
> this%lens = 0
> to_s: do i = digits(0), 1, -1
> rem = mod( n, 10 )
> this%s(i:i) = achar(iachar("0") + rem)
> this%lens = this%lens + 1
> n = n/10
> if ( n == 0 ) exit to_s
> end do to_s
> this%s = adjustl(this%s)
> end subroutine
> subroutine write_s( dtv, lun, iotype, vlist, istat, imsg )
> ! Argument list
> class(num_string_t), intent(in) :: dtv
> integer, intent(in) :: lun
> character(len=*), intent(in) :: iotype
> integer, intent(in) :: vlist(:)
> integer, intent(out) :: istat
> character (len=*), intent(inout) :: imsg
> ! local variable
> character(len=20) :: pfmt
> istat = 0
> select case ( iotype )
> case ( "LISTDIRECTED" )
> ! No special consideration
> write(lun, fmt=*, iostat=istat, iomsg=imsg) dtv%s(:dtv%lens) // new_line("")
> case ( "DT" )
> ! vlist(1) is to be used as the field widths of the
> ! component of the derived type variable. First set up the format to
> ! be used for output.
> if ( size(vlist) > 0 ) then
> write(pfmt,"(*(g0))" ) "(1x,g", vlist(1), ")"
> else
> pfmt = "(1x,g0)"
> end if
> write(lun, fmt=pfmt, advance="no", iostat=istat, iomsg=imsg) dtv%s(:dtv%lens) // new_line("")
> case ( "NAMELIST" )
> ! Not supported
> istat = 1
> imsg = "Namelist option is not yet supported."
> return
> end select
> return
> end subroutine
> end module
> 
> ```

It will be interesting to see how much adversely the performance might be affected when complicated options using modern Fortran are in play.

Also, the determination of the **“FizzBuzz”** values themselves has gotta be an **embarrassingly parallel** problem for a processor, so the question is whether a Fortran processor fed with `coarray`s and aided by `DO CONCURRENT` gets close achieving it following which it is just a matter of IO of large data.

---

_[View the full topic](https://fortran-lang.discourse.group/t/fizzbuzz-in-fortran-much-slower-than-in-c/2339)._
